summaryrefslogtreecommitdiffstats
path: root/src/plugins
diff options
context:
space:
mode:
authorQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2018-07-17 01:00:21 +0200
committerEdward Welbourne <edward.welbourne@qt.io>2018-07-17 10:19:22 +0200
commit1783fca89768a9d503d886673643dc4542ec467f (patch)
tree5055f39393017219e448ade71b3842896c4679c5 /src/plugins
parentb82648bd59256abb8e7084e0424a1f8a6a034c34 (diff)
parent435d1d53bd61491010dbb2130a27e35cd9798965 (diff)
Merge remote-tracking branch 'origin/5.11' into dev
Conflicts: src/plugins/platforms/cocoa/qcocoawindow.mm src/plugins/platforms/xcb/qxcbintegration.cpp Conflicts git missed: src/plugins/platforms/qnx/qqnxglcontext.cpp Change-Id: I0582cdc9e66e43efe79038b9c43d4f9572ac88fc
Diffstat (limited to 'src/plugins')
-rw-r--r--src/plugins/platforms/bsdfb/qbsdfbscreen.h2
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.mm33
-rw-r--r--src/plugins/platforms/qnx/qqnxglcontext.cpp13
-rw-r--r--src/plugins/platforms/qnx/qqnxintegration.cpp4
-rw-r--r--src/plugins/platforms/qnx/qqnxintegration.h3
-rw-r--r--src/plugins/platforms/winrt/qwinrtscreen.cpp5
-rw-r--r--src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp2
-rw-r--r--src/plugins/platforms/xcb/gl_integrations/xcb_glx/qxcbglxintegration.cpp2
-rw-r--r--src/plugins/platforms/xcb/nativepainting/qbackingstore_x11.cpp2
-rw-r--r--src/plugins/platforms/xcb/nativepainting/qt_x11_p.h2
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.cpp9
-rw-r--r--src/plugins/platforms/xcb/qxcbintegration.cpp2
-rw-r--r--src/plugins/platforms/xcb/qxcbscreen.cpp186
-rw-r--r--src/plugins/platforms/xcb/qxcbscreen.h10
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.cpp2
-rw-r--r--src/plugins/platforms/xcb/qxcbxsettings.cpp1
16 files changed, 161 insertions, 117 deletions
diff --git a/src/plugins/platforms/bsdfb/qbsdfbscreen.h b/src/plugins/platforms/bsdfb/qbsdfbscreen.h
index 890a2eb757..6002e3664e 100644
--- a/src/plugins/platforms/bsdfb/qbsdfbscreen.h
+++ b/src/plugins/platforms/bsdfb/qbsdfbscreen.h
@@ -54,7 +54,7 @@ public:
explicit QBsdFbScreen(const QStringList &args);
~QBsdFbScreen() override;
- bool initialize();
+ bool initialize() override;
QPixmap grabWindow(WId wid, int x, int y, int width, int height) const override;
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm
index 0e7255e997..c916ae41de 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.mm
+++ b/src/plugins/platforms/cocoa/qcocoawindow.mm
@@ -1503,6 +1503,15 @@ QCocoaNSWindow *QCocoaWindow::createNSWindow(bool shouldBePanel)
{
QMacAutoReleasePool pool;
+ Qt::WindowType type = window()->type();
+ Qt::WindowFlags flags = window()->flags();
+
+ // Note: The macOS window manager has a bug, where if a screen is rotated, it will not allow
+ // a window to be created within the area of the screen that has a Y coordinate (I quadrant)
+ // higher than the height of the screen in its non-rotated state, unless the window is
+ // created with the NSWindowStyleMaskBorderless style mask.
+ NSWindowStyleMask styleMask = windowStyleMask(flags);
+
QRect rect = geometry();
QScreen *targetScreen = nullptr;
@@ -1514,26 +1523,22 @@ QCocoaNSWindow *QCocoaWindow::createNSWindow(bool shouldBePanel)
}
if (!targetScreen) {
- qCWarning(lcQpaWindow) << "Window position outside any known screen, using primary screen";
+ qCWarning(lcQpaWindow) << "Window position" << rect << "outside any known screen, using primary screen";
targetScreen = QGuiApplication::primaryScreen();
+ // AppKit will only reposition a window that's outside the target screen area if
+ // the window has a title bar. If left out, the window ends up with no screen.
+ // The style mask will be corrected to the original style mask in setWindowFlags.
+ styleMask |= NSWindowStyleMaskTitled;
}
rect.translate(-targetScreen->geometry().topLeft());
QCocoaScreen *cocoaScreen = static_cast<QCocoaScreen *>(targetScreen->handle());
NSRect frame = QCocoaScreen::mapToNative(rect, cocoaScreen);
- // Note: The macOS window manager has a bug, where if a screen is rotated, it will not allow
- // a window to be created within the area of the screen that has a Y coordinate (I quadrant)
- // higher than the height of the screen in its non-rotated state, unless the window is
- // created with the NSWindowStyleMaskBorderless style mask.
-
- Qt::WindowType type = window()->type();
- Qt::WindowFlags flags = window()->flags();
-
// Create NSWindow
Class windowClass = shouldBePanel ? [QNSPanel class] : [QNSWindow class];
QCocoaNSWindow *nsWindow = [[windowClass alloc] initWithContentRect:frame
- styleMask:windowStyleMask(flags)
+ styleMask:styleMask
// Deferring window creation breaks OpenGL (the GL context is
// set up before the window is shown and needs a proper window)
backing:NSBackingStoreBuffered defer:NO
@@ -1542,6 +1547,11 @@ QCocoaNSWindow *QCocoaWindow::createNSWindow(bool shouldBePanel)
Q_ASSERT_X(nsWindow.screen == cocoaScreen->nativeScreen(), "QCocoaWindow",
"Resulting NSScreen should match the requested NSScreen");
+ if (targetScreen != window()->screen()) {
+ QWindowSystemInterface::handleWindowScreenChanged<
+ QWindowSystemInterface::SynchronousDelivery>(window(), targetScreen);
+ }
+
nsWindow.delegate = [[QNSWindowDelegate alloc] initWithQCocoaWindow:this];
// Prevent Cocoa from releasing the window on close. Qt
@@ -1561,9 +1571,6 @@ QCocoaNSWindow *QCocoaWindow::createNSWindow(bool shouldBePanel)
});
}
- if (targetScreen != window()->screen())
- QWindowSystemInterface::handleWindowScreenChanged<QWindowSystemInterface::SynchronousDelivery>(window(), targetScreen);
-
nsWindow.restorable = NO;
nsWindow.level = windowLevel(flags);
diff --git a/src/plugins/platforms/qnx/qqnxglcontext.cpp b/src/plugins/platforms/qnx/qqnxglcontext.cpp
index d4493943e2..1d030ba1aa 100644
--- a/src/plugins/platforms/qnx/qqnxglcontext.cpp
+++ b/src/plugins/platforms/qnx/qqnxglcontext.cpp
@@ -38,6 +38,7 @@
****************************************************************************/
#include "qqnxglcontext.h"
+#include "qqnxintegration.h"
#include "qqnxscreen.h"
#include "qqnxeglwindow.h"
@@ -59,8 +60,18 @@ QT_BEGIN_NAMESPACE
EGLDisplay QQnxGLContext::ms_eglDisplay = EGL_NO_DISPLAY;
+static QEGLPlatformContext::Flags makeFlags()
+{
+ QEGLPlatformContext::Flags result = 0;
+
+ if (!QQnxIntegration::instance()->options().testFlag(QQnxIntegration::SurfacelessEGLContext))
+ result |= QEGLPlatformContext::NoSurfaceless;
+
+ return result;
+}
+
QQnxGLContext::QQnxGLContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share)
- : QEGLPlatformContext(format, share, ms_eglDisplay)
+ : QEGLPlatformContext(format, share, ms_eglDisplay, 0, QVariant(), makeFlags())
{
}
diff --git a/src/plugins/platforms/qnx/qqnxintegration.cpp b/src/plugins/platforms/qnx/qqnxintegration.cpp
index 0b6a7f197a..8c8521325c 100644
--- a/src/plugins/platforms/qnx/qqnxintegration.cpp
+++ b/src/plugins/platforms/qnx/qqnxintegration.cpp
@@ -116,6 +116,10 @@ static inline QQnxIntegration::Options parseOptions(const QStringList &paramList
options |= QQnxIntegration::RootWindow;
}
+ if (!paramList.contains(QLatin1String("disable-EGL_KHR_surfaceless_context"))) {
+ options |= QQnxIntegration::SurfacelessEGLContext;
+ }
+
return options;
}
diff --git a/src/plugins/platforms/qnx/qqnxintegration.h b/src/plugins/platforms/qnx/qqnxintegration.h
index 89654f588f..2993607489 100644
--- a/src/plugins/platforms/qnx/qqnxintegration.h
+++ b/src/plugins/platforms/qnx/qqnxintegration.h
@@ -81,7 +81,8 @@ public:
NoOptions = 0x0,
FullScreenApplication = 0x1,
RootWindow = 0x2,
- AlwaysFlushScreenContext = 0x4
+ AlwaysFlushScreenContext = 0x4,
+ SurfacelessEGLContext = 0x8
};
Q_DECLARE_FLAGS(Options, Option)
explicit QQnxIntegration(const QStringList &paramList);
diff --git a/src/plugins/platforms/winrt/qwinrtscreen.cpp b/src/plugins/platforms/winrt/qwinrtscreen.cpp
index 7e71b6faf1..2e79c3505b 100644
--- a/src/plugins/platforms/winrt/qwinrtscreen.cpp
+++ b/src/plugins/platforms/winrt/qwinrtscreen.cpp
@@ -1268,7 +1268,8 @@ HRESULT QWinRTScreen::onPointerUpdated(ICoreWindow *, IPointerEventArgs *args)
it.value().id = id;
}
- if (isPressed && it.value().pressure == 0.)
+ const bool wasPressEvent = isPressed && it.value().pressure == 0.;
+ if (wasPressEvent)
it.value().state = Qt::TouchPointPressed;
else if (!isPressed && it.value().pressure > 0.)
it.value().state = Qt::TouchPointReleased;
@@ -1282,6 +1283,8 @@ HRESULT QWinRTScreen::onPointerUpdated(ICoreWindow *, IPointerEventArgs *args)
it.value().pressure = pressure;
QWindowSystemInterface::handleTouchEvent(d->currentTargetWindow, d->touchDevice, d->touchPoints.values(), mods);
+ if (wasPressEvent)
+ it.value().state = Qt::TouchPointStationary;
// Fall-through for pen to generate tablet event
if (pointerDeviceType != PointerDeviceType_Pen)
diff --git a/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp
index cc982b3379..741885e321 100644
--- a/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp
+++ b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp
@@ -45,8 +45,10 @@
#include "qxcbwindow.h"
#include "qxcbscreen.h"
+#define register /* C++17 deprecated register */
#include <X11/Xlib.h>
#include <X11/Xutil.h>
+#undef register
#include <GL/glx.h>
#include <QtGui/QOpenGLContext>
diff --git a/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qxcbglxintegration.cpp b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qxcbglxintegration.cpp
index 13f03f8bf3..a7641baea1 100644
--- a/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qxcbglxintegration.cpp
+++ b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qxcbglxintegration.cpp
@@ -52,7 +52,9 @@
#include "qxcbglxnativeinterfacehandler.h"
+#define register /* C++17 deprecated register */
#include <X11/Xlibint.h>
+#undef register
QT_BEGIN_NAMESPACE
diff --git a/src/plugins/platforms/xcb/nativepainting/qbackingstore_x11.cpp b/src/plugins/platforms/xcb/nativepainting/qbackingstore_x11.cpp
index 9b31998620..8851ea59e5 100644
--- a/src/plugins/platforms/xcb/nativepainting/qbackingstore_x11.cpp
+++ b/src/plugins/platforms/xcb/nativepainting/qbackingstore_x11.cpp
@@ -48,7 +48,9 @@
# include <X11/extensions/Xrender.h>
#endif
+#define register /* C++17 deprecated register */
#include <X11/Xlib.h>
+#undef register
#ifndef None
#define None 0L
diff --git a/src/plugins/platforms/xcb/nativepainting/qt_x11_p.h b/src/plugins/platforms/xcb/nativepainting/qt_x11_p.h
index aa8dfa5af0..a13a8f0483 100644
--- a/src/plugins/platforms/xcb/nativepainting/qt_x11_p.h
+++ b/src/plugins/platforms/xcb/nativepainting/qt_x11_p.h
@@ -40,8 +40,10 @@
#ifndef QT_X11_P_H
#define QT_X11_P_H
+#define register /* C++17 deprecated register */
#include <X11/Xlib.h>
#include <X11/Xatom.h>
+#undef register
#if QT_CONFIG(xrender)
# include "qtessellator_p.h"
diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp
index 01e67039f1..b4ccb808a0 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection.cpp
@@ -74,10 +74,12 @@
#include <xcb/xinerama.h>
#if QT_CONFIG(xcb_xlib)
+#define register /* C++17 deprecated register */
#include <X11/Xlib.h>
#include <X11/Xlib-xcb.h>
#include <X11/Xlibint.h>
#include <X11/Xutil.h>
+#undef register
#endif
#if QT_CONFIG(xcb_xinput)
@@ -1213,10 +1215,9 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event)
handled = true;
} else if (has_randr_extension && response_type == xrandr_first_event + XCB_RANDR_SCREEN_CHANGE_NOTIFY) {
xcb_randr_screen_change_notify_event_t *change_event = reinterpret_cast<xcb_randr_screen_change_notify_event_t *>(event);
- for (QXcbScreen *s : qAsConst(m_screens)) {
- if (s->root() == change_event->root )
- s->handleScreenChange(change_event);
- }
+ if (auto *virtualDesktop = virtualDesktopForRootWindow(change_event->root))
+ virtualDesktop->handleScreenChange(change_event);
+
handled = true;
#if QT_CONFIG(xkb)
} else if (response_type == xkb_first_event) { // https://bugs.freedesktop.org/show_bug.cgi?id=51295
diff --git a/src/plugins/platforms/xcb/qxcbintegration.cpp b/src/plugins/platforms/xcb/qxcbintegration.cpp
index d873d26ebd..e9b36c48b8 100644
--- a/src/plugins/platforms/xcb/qxcbintegration.cpp
+++ b/src/plugins/platforms/xcb/qxcbintegration.cpp
@@ -66,7 +66,9 @@
#include <QtGui/private/qguiapplication_p.h>
#if QT_CONFIG(xcb_xlib)
+#define register /* C++17 deprecated register */
#include <X11/Xlib.h>
+#undef register
#endif
#if QT_CONFIG(xcb_native_painting)
#include "qxcbnativepainting.h"
diff --git a/src/plugins/platforms/xcb/qxcbscreen.cpp b/src/plugins/platforms/xcb/qxcbscreen.cpp
index dd7e054301..b398768bbc 100644
--- a/src/plugins/platforms/xcb/qxcbscreen.cpp
+++ b/src/plugins/platforms/xcb/qxcbscreen.cpp
@@ -112,6 +112,13 @@ QXcbVirtualDesktop::QXcbVirtualDesktop(QXcbConnection *connection, xcb_screen_t
xcb_depth_next(&depth_iterator);
}
+
+ if (connection->hasXRandr()) {
+ xcb_connection_t *conn = connection->xcb_connection();
+ auto screen_info = Q_XCB_REPLY(xcb_randr_get_screen_info, conn, screen->root);
+ if (screen_info)
+ m_rotation = screen_info->rotation;
+ }
}
QXcbVirtualDesktop::~QXcbVirtualDesktop()
@@ -119,6 +126,15 @@ QXcbVirtualDesktop::~QXcbVirtualDesktop()
delete m_xSettings;
}
+QDpi QXcbVirtualDesktop::dpi() const
+{
+ const QSize virtualSize = size();
+ const QSize virtualSizeMillimeters = physicalSize();
+
+ return QDpi(Q_MM_PER_INCH * virtualSize.width() / virtualSizeMillimeters.width(),
+ Q_MM_PER_INCH * virtualSize.height() / virtualSizeMillimeters.height());
+}
+
QXcbScreen *QXcbVirtualDesktop::screenAt(const QPoint &pos) const
{
const auto screens = connection()->screens();
@@ -174,6 +190,74 @@ void QXcbVirtualDesktop::subscribeToXFixesSelectionNotify()
}
}
+/*!
+ \brief handle the XCB screen change event and update properties
+
+ On a mobile device, the ideal use case is that the accelerometer would
+ drive the orientation. This could be achieved by using QSensors to read the
+ accelerometer and adjusting the rotation in QML, or by reading the
+ orientation from the QScreen object and doing the same, or in many other
+ ways. However, on X we have the XRandR extension, which makes it possible
+ to have the whole screen rotated, so that individual apps DO NOT have to
+ rotate themselves. Apps could optionally use the
+ QScreen::primaryOrientation property to optimize layout though.
+ Furthermore, there is no support in X for accelerometer events anyway. So
+ it makes more sense on a Linux system running X to just run a daemon which
+ monitors the accelerometer and runs xrandr automatically to do the rotation,
+ then apps do not have to be aware of it (but probably the window manager
+ would resize them accordingly). updateGeometry() is written with this
+ design in mind. Therefore the physical geometry, available geometry,
+ virtual geometry, orientation and primaryOrientation should all change at
+ the same time. On a system which cannot rotate the whole screen, it would
+ be correct for only the orientation (not the primary orientation) to
+ change.
+*/
+void QXcbVirtualDesktop::handleScreenChange(xcb_randr_screen_change_notify_event_t *change_event)
+{
+ // No need to do anything when screen rotation did not change - if any
+ // xcb output geometry has changed, we will get RRCrtcChangeNotify and
+ // RROutputChangeNotify events next
+ if (change_event->rotation == m_rotation)
+ return;
+
+ m_rotation = change_event->rotation;
+ switch (m_rotation) {
+ case XCB_RANDR_ROTATION_ROTATE_0: // xrandr --rotate normal
+ m_screen->width_in_pixels = change_event->width;
+ m_screen->height_in_pixels = change_event->height;
+ m_screen->width_in_millimeters = change_event->mwidth;
+ m_screen->height_in_millimeters = change_event->mheight;
+ break;
+ case XCB_RANDR_ROTATION_ROTATE_90: // xrandr --rotate left
+ m_screen->width_in_pixels = change_event->height;
+ m_screen->height_in_pixels = change_event->width;
+ m_screen->width_in_millimeters = change_event->mheight;
+ m_screen->height_in_millimeters = change_event->mwidth;
+ break;
+ case XCB_RANDR_ROTATION_ROTATE_180: // xrandr --rotate inverted
+ m_screen->width_in_pixels = change_event->width;
+ m_screen->height_in_pixels = change_event->height;
+ m_screen->width_in_millimeters = change_event->mwidth;
+ m_screen->height_in_millimeters = change_event->mheight;
+ break;
+ case XCB_RANDR_ROTATION_ROTATE_270: // xrandr --rotate right
+ m_screen->width_in_pixels = change_event->height;
+ m_screen->height_in_pixels = change_event->width;
+ m_screen->width_in_millimeters = change_event->mheight;
+ m_screen->height_in_millimeters = change_event->mwidth;
+ break;
+ // We don't need to do anything with these, since QScreen doesn't store reflection state,
+ // and Qt-based applications probably don't need to care about it anyway.
+ case XCB_RANDR_ROTATION_REFLECT_X: break;
+ case XCB_RANDR_ROTATION_REFLECT_Y: break;
+ }
+
+ for (QPlatformScreen *platformScreen: qAsConst(m_screens)) {
+ QDpi ldpi = platformScreen->logicalDpi();
+ QWindowSystemInterface::handleScreenLogicalDotsPerInchChange(platformScreen->screen(), ldpi.first, ldpi.second);
+ }
+}
+
/*! \internal
Using _NET_WORKAREA to calculate the available desktop geometry on multi-head systems (systems
@@ -401,8 +485,6 @@ QXcbScreen::QXcbScreen(QXcbConnection *connection, QXcbVirtualDesktop *virtualDe
, m_crtc(output ? output->crtc : XCB_NONE)
, m_outputName(getOutputName(output))
, m_outputSizeMillimeters(output ? QSize(output->mm_width, output->mm_height) : QSize())
- , m_virtualSize(virtualDesktop->size())
- , m_virtualSizeMillimeters(virtualDesktop->physicalSize())
{
if (connection->hasXRandr()) {
xcb_randr_select_input(xcb_connection(), screen()->root, true);
@@ -416,19 +498,19 @@ QXcbScreen::QXcbScreen(QXcbConnection *connection, QXcbVirtualDesktop *virtualDe
m_geometry = QRect(xineramaScreenInfo->x_org, xineramaScreenInfo->y_org,
xineramaScreenInfo->width, xineramaScreenInfo->height);
m_availableGeometry = m_geometry & m_virtualDesktop->workArea();
- m_sizeMillimeters = sizeInMillimeters(m_geometry.size(), virtualDpi());
+ m_sizeMillimeters = sizeInMillimeters(m_geometry.size(), m_virtualDesktop->dpi());
if (xineramaScreenIdx > -1)
m_outputName += QLatin1Char('-') + QString::number(xineramaScreenIdx);
}
if (m_geometry.isEmpty())
- m_geometry = QRect(QPoint(), m_virtualSize);
+ m_geometry = QRect(QPoint(), virtualDesktop->size());
if (m_availableGeometry.isEmpty())
m_availableGeometry = m_geometry & m_virtualDesktop->workArea();
if (m_sizeMillimeters.isEmpty())
- m_sizeMillimeters = m_virtualSizeMillimeters;
+ m_sizeMillimeters = virtualDesktop->physicalSize();
m_cursor = new QXcbCursor(connection, this);
@@ -583,13 +665,6 @@ QImage::Format QXcbScreen::format() const
return format;
}
-QDpi QXcbScreen::virtualDpi() const
-{
- return QDpi(Q_MM_PER_INCH * m_virtualSize.width() / m_virtualSizeMillimeters.width(),
- Q_MM_PER_INCH * m_virtualSize.height() / m_virtualSizeMillimeters.height());
-}
-
-
QDpi QXcbScreen::logicalDpi() const
{
static const int overrideDpi = qEnvironmentVariableIntValue("QT_FONT_DPI");
@@ -600,7 +675,7 @@ QDpi QXcbScreen::logicalDpi() const
if (forcedDpi > 0) {
return QDpi(forcedDpi, forcedDpi);
}
- return virtualDpi();
+ return m_virtualDesktop->dpi();
}
qreal QXcbScreen::pixelDensity() const
@@ -631,80 +706,6 @@ int QXcbScreen::virtualDesktopNumberStatic(const QScreen *screen)
return 0;
}
-/*!
- \brief handle the XCB screen change event and update properties
-
- On a mobile device, the ideal use case is that the accelerometer would
- drive the orientation. This could be achieved by using QSensors to read the
- accelerometer and adjusting the rotation in QML, or by reading the
- orientation from the QScreen object and doing the same, or in many other
- ways. However, on X we have the XRandR extension, which makes it possible
- to have the whole screen rotated, so that individual apps DO NOT have to
- rotate themselves. Apps could optionally use the
- QScreen::primaryOrientation property to optimize layout though.
- Furthermore, there is no support in X for accelerometer events anyway. So
- it makes more sense on a Linux system running X to just run a daemon which
- monitors the accelerometer and runs xrandr automatically to do the rotation,
- then apps do not have to be aware of it (but probably the window manager
- would resize them accordingly). updateGeometry() is written with this
- design in mind. Therefore the physical geometry, available geometry,
- virtual geometry, orientation and primaryOrientation should all change at
- the same time. On a system which cannot rotate the whole screen, it would
- be correct for only the orientation (not the primary orientation) to
- change.
-*/
-void QXcbScreen::handleScreenChange(xcb_randr_screen_change_notify_event_t *change_event)
-{
- // No need to do anything when screen rotation did not change - if any
- // xcb output geometry has changed, we will get RRCrtcChangeNotify and
- // RROutputChangeNotify events next
- if (change_event->rotation == m_rotation)
- return;
-
- m_rotation = change_event->rotation;
- switch (m_rotation) {
- case XCB_RANDR_ROTATION_ROTATE_0: // xrandr --rotate normal
- m_orientation = Qt::LandscapeOrientation;
- m_virtualSize.setWidth(change_event->width);
- m_virtualSize.setHeight(change_event->height);
- m_virtualSizeMillimeters.setWidth(change_event->mwidth);
- m_virtualSizeMillimeters.setHeight(change_event->mheight);
- break;
- case XCB_RANDR_ROTATION_ROTATE_90: // xrandr --rotate left
- m_orientation = Qt::PortraitOrientation;
- m_virtualSize.setWidth(change_event->height);
- m_virtualSize.setHeight(change_event->width);
- m_virtualSizeMillimeters.setWidth(change_event->mheight);
- m_virtualSizeMillimeters.setHeight(change_event->mwidth);
- break;
- case XCB_RANDR_ROTATION_ROTATE_180: // xrandr --rotate inverted
- m_orientation = Qt::InvertedLandscapeOrientation;
- m_virtualSize.setWidth(change_event->width);
- m_virtualSize.setHeight(change_event->height);
- m_virtualSizeMillimeters.setWidth(change_event->mwidth);
- m_virtualSizeMillimeters.setHeight(change_event->mheight);
- break;
- case XCB_RANDR_ROTATION_ROTATE_270: // xrandr --rotate right
- m_orientation = Qt::InvertedPortraitOrientation;
- m_virtualSize.setWidth(change_event->height);
- m_virtualSize.setHeight(change_event->width);
- m_virtualSizeMillimeters.setWidth(change_event->mheight);
- m_virtualSizeMillimeters.setHeight(change_event->mwidth);
- break;
- // We don't need to do anything with these, since QScreen doesn't store reflection state,
- // and Qt-based applications probably don't need to care about it anyway.
- case XCB_RANDR_ROTATION_REFLECT_X: break;
- case XCB_RANDR_ROTATION_REFLECT_Y: break;
- }
-
- updateGeometry(change_event->timestamp);
-
- QWindowSystemInterface::handleScreenOrientationChange(QPlatformScreen::screen(), m_orientation);
-
- QDpi ldpi = logicalDpi();
- QWindowSystemInterface::handleScreenLogicalDotsPerInchChange(QPlatformScreen::screen(), ldpi.first, ldpi.second);
-}
-
void QXcbScreen::updateGeometry(xcb_timestamp_t timestamp)
{
if (!connection()->hasXRandr())
@@ -718,6 +719,8 @@ void QXcbScreen::updateGeometry(xcb_timestamp_t timestamp)
void QXcbScreen::updateGeometry(const QRect &geometry, uint8_t rotation)
{
+ const Qt::ScreenOrientation oldOrientation = m_orientation;
+
switch (rotation) {
case XCB_RANDR_ROTATION_ROTATE_0: // xrandr --rotate normal
m_orientation = Qt::LandscapeOrientation;
@@ -741,13 +744,15 @@ void QXcbScreen::updateGeometry(const QRect &geometry, uint8_t rotation)
// is known (probably back-calculated from DPI and resolution),
// e.g. on VNC or with some hardware.
if (m_sizeMillimeters.isEmpty())
- m_sizeMillimeters = sizeInMillimeters(geometry.size(), virtualDpi());
+ m_sizeMillimeters = sizeInMillimeters(geometry.size(), m_virtualDesktop->dpi());
qreal dpi = geometry.width() / physicalSize().width() * qreal(25.4);
m_pixelDensity = qMax(1, qRound(dpi/96));
m_geometry = geometry;
m_availableGeometry = geometry & m_virtualDesktop->workArea();
QWindowSystemInterface::handleScreenGeometryChange(QPlatformScreen::screen(), m_geometry, m_availableGeometry);
+ if (m_orientation != oldOrientation)
+ QWindowSystemInterface::handleScreenOrientationChange(QPlatformScreen::screen(), m_orientation);
}
void QXcbScreen::updateAvailableGeometry()
@@ -943,8 +948,9 @@ QDebug operator<<(QDebug debug, const QXcbScreen *screen)
formatSizeF(debug, screen->physicalSize());
// TODO 5.6 if (debug.verbosity() > 2) {
debug << ", screenNumber=" << screen->screenNumber();
- debug << ", virtualSize=" << screen->virtualSize().width() << 'x' << screen->virtualSize().height() << " (";
- formatSizeF(debug, screen->virtualSize());
+ const QSize virtualSize = screen->virtualDesktop()->size();
+ debug << ", virtualSize=" << virtualSize.width() << 'x' << virtualSize.height() << " (";
+ formatSizeF(debug, virtualSize);
debug << "), orientation=" << screen->orientation();
debug << ", depth=" << screen->depth();
debug << ", refreshRate=" << screen->refreshRate();
diff --git a/src/plugins/platforms/xcb/qxcbscreen.h b/src/plugins/platforms/xcb/qxcbscreen.h
index 664d972777..e13777f661 100644
--- a/src/plugins/platforms/xcb/qxcbscreen.h
+++ b/src/plugins/platforms/xcb/qxcbscreen.h
@@ -74,6 +74,7 @@ public:
int number() const { return m_number; }
QSize size() const { return QSize(m_screen->width_in_pixels, m_screen->height_in_pixels); }
QSize physicalSize() const { return QSize(m_screen->width_in_millimeters, m_screen->height_in_millimeters); }
+ QDpi dpi() const;
xcb_window_t root() const { return m_screen->root; }
QXcbScreen *screenAt(const QPoint &pos) const;
@@ -93,6 +94,8 @@ public:
void handleXFixesSelectionNotify(xcb_xfixes_selection_notify_event_t *notify_event);
void subscribeToXFixesSelectionNotify();
+ void handleScreenChange(xcb_randr_screen_change_notify_event_t *change_event);
+
int forcedDpi() const { return m_forcedDpi; }
QFontEngine::HintStyle hintStyle() const { return m_hintStyle; }
QFontEngine::SubpixelAntialiasingType subpixelType() const { return m_subpixelType; }
@@ -131,6 +134,7 @@ private:
QString m_windowManagerName;
QMap<xcb_visualid_t, xcb_visualtype_t> m_visuals;
QMap<xcb_visualid_t, quint8> m_visualDepths;
+ uint16_t m_rotation = XCB_RANDR_ROTATION_ROTATE_0;
};
class Q_XCB_EXPORT QXcbScreen : public QXcbObject, public QPlatformScreen
@@ -156,9 +160,6 @@ public:
int depth() const override { return screen()->root_depth; }
QImage::Format format() const override;
QSizeF physicalSize() const override { return m_sizeMillimeters; }
- QSize virtualSize() const { return m_virtualSize; }
- QSizeF physicalVirtualSize() const { return m_virtualSizeMillimeters; }
- QDpi virtualDpi() const;
QDpi logicalDpi() const override;
qreal pixelDensity() const override;
QPlatformCursor *cursor() const override;
@@ -194,7 +195,6 @@ public:
QString name() const override { return m_outputName; }
- void handleScreenChange(xcb_randr_screen_change_notify_event_t *change_event);
void updateGeometry(const QRect &geometry, uint8_t rotation);
void updateGeometry(xcb_timestamp_t timestamp = XCB_TIME_CURRENT_TIME);
void updateAvailableGeometry();
@@ -224,8 +224,6 @@ private:
QSizeF m_sizeMillimeters;
QRect m_geometry;
QRect m_availableGeometry;
- QSize m_virtualSize;
- QSizeF m_virtualSizeMillimeters;
Qt::ScreenOrientation m_orientation = Qt::PrimaryOrientation;
QXcbCursor *m_cursor;
int m_refreshRate = 60;
diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp
index 316adb8fa9..9e9058e6e9 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.cpp
+++ b/src/plugins/platforms/xcb/qxcbwindow.cpp
@@ -106,8 +106,10 @@
#include <stdio.h>
#if QT_CONFIG(xcb_xlib)
+#define register /* C++17 deprecated register */
#include <X11/Xlib.h>
#include <X11/Xutil.h>
+#undef register
#endif
#define XCOORD_MAX 16383
diff --git a/src/plugins/platforms/xcb/qxcbxsettings.cpp b/src/plugins/platforms/xcb/qxcbxsettings.cpp
index bd398ea049..88f15e344f 100644
--- a/src/plugins/platforms/xcb/qxcbxsettings.cpp
+++ b/src/plugins/platforms/xcb/qxcbxsettings.cpp
@@ -244,6 +244,7 @@ QXcbXSettings::QXcbXSettings(QXcbVirtualDesktop *screen)
if (!d_ptr->x_settings_window)
return;
+ screen->connection()->addWindowEventListener(d_ptr->x_settings_window, this);
const uint32_t event = XCB_CW_EVENT_MASK;
const uint32_t event_mask[] = { XCB_EVENT_MASK_STRUCTURE_NOTIFY|XCB_EVENT_MASK_PROPERTY_CHANGE };
xcb_change_window_attributes(screen->xcb_connection(),d_ptr->x_settings_window,event,event_mask);