diff options
Diffstat (limited to 'src/plugins')
-rw-r--r-- | src/plugins/platforms/bsdfb/qbsdfbscreen.h | 2 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoawindow.mm | 33 | ||||
-rw-r--r-- | src/plugins/platforms/qnx/qqnxglcontext.cpp | 13 | ||||
-rw-r--r-- | src/plugins/platforms/qnx/qqnxintegration.cpp | 4 | ||||
-rw-r--r-- | src/plugins/platforms/qnx/qqnxintegration.h | 3 | ||||
-rw-r--r-- | src/plugins/platforms/winrt/qwinrtscreen.cpp | 5 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp | 2 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/gl_integrations/xcb_glx/qxcbglxintegration.cpp | 2 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/nativepainting/qbackingstore_x11.cpp | 2 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/nativepainting/qt_x11_p.h | 2 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbconnection.cpp | 9 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbintegration.cpp | 2 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbscreen.cpp | 186 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbscreen.h | 10 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbwindow.cpp | 2 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbxsettings.cpp | 1 |
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 ¶mList 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 ¶mList); 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); |