From c6386a503c3f5a9d95102c2fc9ab6faf468e7d37 Mon Sep 17 00:00:00 2001 From: Rex Dieter Date: Fri, 11 Dec 2015 22:39:20 -0600 Subject: [PATCH 1/3] unused patches --- ...ling-of-outputs-in-the-middle-of-the.patch | 56 --- 138201.patch | 386 ------------------ 2 files changed, 442 deletions(-) delete mode 100644 0197-xcb-Ignore-disabling-of-outputs-in-the-middle-of-the.patch delete mode 100644 138201.patch diff --git a/0197-xcb-Ignore-disabling-of-outputs-in-the-middle-of-the.patch b/0197-xcb-Ignore-disabling-of-outputs-in-the-middle-of-the.patch deleted file mode 100644 index 364426e..0000000 --- a/0197-xcb-Ignore-disabling-of-outputs-in-the-middle-of-the.patch +++ /dev/null @@ -1,56 +0,0 @@ -From ae51e360f986698eaf41fdb38f8a878a50f69be1 Mon Sep 17 00:00:00 2001 -From: Alexander Volkov -Date: Fri, 19 Jun 2015 13:34:11 +0300 -Subject: [PATCH 197/412] xcb: Ignore disabling of outputs in the middle of the - mode switch -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -X server may send RROutputChangeNotify event with null crtc and mode, -when it switches an output mode. Request RROutputInfo to distinguish -this case from the case when the output is explicitly disabled. - -Change-Id: I4c2356ec71dbcc8013009ea8a6f46dd11f19d6bb -Task-number: QTBUG-44158 -Task-number: QTBUG-46786 -Task-number: QTBUG-46822 -Reviewed-by: Daniel Vrátil -Reviewed-by: Gatis Paeglis -Reviewed-by: Shawn Rutledge ---- - src/plugins/platforms/xcb/qxcbconnection.cpp | 18 +++++++++++++----- - 1 file changed, 13 insertions(+), 5 deletions(-) - -diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp -index 0867615..29e1fd1 100644 ---- a/src/plugins/platforms/xcb/qxcbconnection.cpp -+++ b/src/plugins/platforms/xcb/qxcbconnection.cpp -@@ -265,11 +265,19 @@ void QXcbConnection::updateScreens(const xcb_randr_notify_event_t *event) - } else if (screen) { - // Screen has been disabled -> remove - if (output.crtc == XCB_NONE && output.mode == XCB_NONE) { -- qCDebug(lcQpaScreen) << "output" << screen->name() << "has been disabled"; -- m_screens.removeOne(screen); -- foreach (QXcbScreen *otherScreen, m_screens) -- otherScreen->removeVirtualSibling((QPlatformScreen *) screen); -- QXcbIntegration::instance()->destroyScreen(screen); -+ xcb_randr_get_output_info_cookie_t outputInfoCookie = -+ xcb_randr_get_output_info(xcb_connection(), output.output, output.config_timestamp); -+ QScopedPointer outputInfo( -+ xcb_randr_get_output_info_reply(xcb_connection(), outputInfoCookie, NULL)); -+ 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); -+ QXcbIntegration::instance()->destroyScreen(screen); -+ } else { -+ qCDebug(lcQpaScreen) << "output" << screen->name() << "has been temporarily disabled for the mode switch"; -+ } - } else { - // Just update existing screen - screen->updateGeometry(output.config_timestamp); --- -2.5.0 - diff --git a/138201.patch b/138201.patch deleted file mode 100644 index 4033b91..0000000 --- a/138201.patch +++ /dev/null @@ -1,386 +0,0 @@ -diff -rupN qtbase-opensource-src-5.5.1/src/plugins/platforms/xcb/qxcbconnection.cpp qtbase-opensource-src-5.5.1-new/src/plugins/platforms/xcb/qxcbconnection.cpp ---- qtbase-opensource-src-5.5.1/src/plugins/platforms/xcb/qxcbconnection.cpp 2015-10-13 06:35:27.000000000 +0200 -+++ qtbase-opensource-src-5.5.1-new/src/plugins/platforms/xcb/qxcbconnection.cpp 2015-10-21 21:02:53.056198256 +0200 -@@ -229,7 +229,6 @@ void QXcbConnection::updateScreens(const - if (screen->mode() != crtc.mode) - screen->updateRefreshRate(crtc.mode); - } -- - } else if (event->subCode == XCB_RANDR_NOTIFY_OUTPUT_CHANGE) { - xcb_randr_output_change_t output = event->u.oc; - QXcbVirtualDesktop *virtualDesktop = virtualDesktopForRootWindow(output.window); -@@ -242,20 +241,18 @@ void QXcbConnection::updateScreens(const - - if (screen && output.connection == XCB_RANDR_CONNECTION_DISCONNECTED) { - qCDebug(lcQpaScreen) << "screen" << screen->name() << "has been disconnected"; -- -- // Known screen removed -> delete it -- m_screens.removeOne(screen); -- foreach (QXcbScreen *otherScreen, m_screens) -- otherScreen->removeVirtualSibling((QPlatformScreen *) screen); -- -- QXcbIntegration::instance()->destroyScreen(screen); -- -- // QTBUG-40174, QTBUG-42985: If all screens are removed, wait -- // and start rendering again later if a screen becomes available. -- -+ destroyScreen(screen, true); - } else if (!screen && output.connection == XCB_RANDR_CONNECTION_CONNECTED) { - // New XRandR output is available and it's enabled - if (output.crtc != XCB_NONE && output.mode != XCB_NONE) { -+ // QTBUG-40174, QTBUG-42985: If virtual screen exists, -+ // remove it and next add a physical screen. -+ if (m_onlyVirtualScreen) { -+ qCDebug(lcQpaScreen) << "default screen" << screen->name() << "has been removed"; -+ destroyScreen(m_screens.at(0), false); -+ m_onlyVirtualScreen = false; -+ } -+ - xcb_randr_get_output_info_cookie_t outputInfoCookie = - xcb_randr_get_output_info(xcb_connection(), output.output, output.config_timestamp); - QScopedPointer outputInfo( -@@ -270,34 +267,25 @@ void QXcbConnection::updateScreens(const - otherScreen->addVirtualSibling(screen); - m_screens << screen; - QXcbIntegration::instance()->screenAdded(screen, screen->isPrimary()); -- -- // Windows which had null screens have already had expose events by now. -- // They need to be told the screen is back, it's OK to render. -- foreach (QWindow *window, QGuiApplication::topLevelWindows()) { -- QXcbWindow *xcbWin = static_cast(window->handle()); -- if (xcbWin) -- xcbWin->maybeSetScreen(screen); -- } -+ maybeSetScreenForTopLevelWindows(screen); - } -- // else ignore disabled screens - } else if (screen) { -- // Screen has been disabled -> remove - if (output.crtc == XCB_NONE && output.mode == XCB_NONE) { -+ // Screen has been disabled - xcb_randr_get_output_info_cookie_t outputInfoCookie = - xcb_randr_get_output_info(xcb_connection(), output.output, output.config_timestamp); - QScopedPointer outputInfo( - xcb_randr_get_output_info_reply(xcb_connection(), outputInfoCookie, NULL)); - 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); -- QXcbIntegration::instance()->destroyScreen(screen); -+ destroyScreen(screen, true); - } else { - qCDebug(lcQpaScreen) << "output" << screen->name() << "has been temporarily disabled for the mode switch"; -+ screen->setCrtc(XCB_NONE); //Invalidate crtc - } - } else { - // Just update existing screen -+ screen->setCrtc(output.crtc); //Set the new crtc, because it may be invalidated - screen->updateGeometry(output.config_timestamp); - const bool wasPrimary = screen->isPrimary(); - screen->setPrimary(checkOutputIsPrimary(output.window, output.output)); -@@ -316,19 +304,61 @@ void QXcbConnection::updateScreens(const - qCDebug(lcQpaScreen) << "output has changed" << screen; - } - } -+ - if (!m_screens.isEmpty()) - qCDebug(lcQpaScreen) << "primary output is" << m_screens.first()->name(); - else - qCDebug(lcQpaScreen) << "no outputs"; - } - } -+void QXcbConnection::destroyScreen(QXcbScreen *screen, bool canCreateVirtualScreen) -+{ -+ // Known screen removed -> delete it -+ m_screens.removeOne(screen); -+ foreach (QXcbScreen *otherScreen, m_screens) -+ otherScreen->removeVirtualSibling((QPlatformScreen *)screen); -+ QXcbIntegration::instance()->destroyScreen(screen); -+ -+ // QTBUG-40174, QTBUG-42985: If all screens are removed, add a virtual -+ // screen and remove it later if a physical screen becomes available. -+ if (canCreateVirtualScreen && m_screens.isEmpty()) -+ createVirtualScreen(); -+} -+void QXcbConnection::createVirtualScreen() -+{ -+ QXcbVirtualDesktop *virtualDesktop = m_virtualDesktops.value(0); -+ if (virtualDesktop && !virtualDesktop->size().isEmpty()) { -+ Q_ASSERT(m_screens.isEmpty()); -+ QXcbScreen *screen = createScreen(virtualDesktop, 0, Q_NULLPTR); -+ screen->setVirtualSiblings(QList() << screen); -+ screen->setPrimary(true); -+ m_onlyVirtualScreen = true; -+ m_screens << screen; -+ QXcbIntegration::instance()->screenAdded(screen, screen->isPrimary()); -+ maybeSetScreenForTopLevelWindows(screen); -+ qCDebug(lcQpaScreen) << "virtual screen was created" << screen; -+ } -+} -+void QXcbConnection::maybeSetScreenForTopLevelWindows(QXcbScreen *screen) -+{ -+ // Windows which had null screens have already had expose events by now. -+ // They need to be told the screen is back, it's OK to render. -+ bool doFlush = false; -+ foreach (QWindow *window, QGuiApplication::topLevelWindows()) { -+ QXcbWindow *xcbWin = static_cast(window->handle()); -+ if (xcbWin) -+ doFlush |= xcbWin->maybeSetScreen(screen); -+ } -+ // Flush Window System Events to prevent disappearing windows -+ if (doFlush) -+ QWindowSystemInterface::flushWindowSystemEvents(); -+} - - void QXcbConnection::initializeScreens() - { - xcb_screen_iterator_t it = xcb_setup_roots_iterator(m_setup); - int xcbScreenNumber = 0; // screen number in the xcb sense - QXcbScreen* primaryScreen = Q_NULLPTR; -- bool hasOutputs = false; - while (it.rem) { - // Each "screen" in xcb terminology is a virtual desktop, - // potentially a collection of separate juxtaposed monitors. -@@ -407,7 +437,6 @@ void QXcbConnection::initializeScreens() - - QXcbScreen *screen = createScreen(virtualDesktop, outputs[i], output.data()); - siblings << screen; -- hasOutputs = true; - m_screens << screen; - - // There can be multiple outputs per screen, use either -@@ -434,39 +463,23 @@ void QXcbConnection::initializeScreens() - ++xcbScreenNumber; - } // for each xcb screen - -- // If there's no randr extension, or there was some error above, or we found a -- // screen which doesn't have outputs for some other reason (e.g. on VNC or ssh -X), -- // but the dimensions are known anyway, and we don't already have any lingering -- // (possibly disconnected) screens, then showing windows should be possible, -- // so create one screen. (QTBUG-31389) -- 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() << screen); -- m_screens << screen; -- primaryScreen = screen; -- primaryScreen->setPrimary(true); -- qCDebug(lcQpaScreen) << "found a screen with zero outputs" << screen; -- } -- -- // Ensure the primary screen is first in the list -- if (primaryScreen) { -- Q_ASSERT(!m_screens.isEmpty()); -- if (m_screens.first() != primaryScreen) { -- m_screens.removeOne(primaryScreen); -- m_screens.prepend(primaryScreen); -+ if (m_screens.isEmpty()) { -+ createVirtualScreen(); -+ } else { -+ // Ensure the primary screen is first in the list -+ if (primaryScreen) { -+ if (m_screens.first() != primaryScreen) { -+ m_screens.removeOne(primaryScreen); -+ m_screens.prepend(primaryScreen); -+ } - } -- } - -- // Push the screens to QApplication -- QXcbIntegration *integration = QXcbIntegration::instance(); -- foreach (QXcbScreen* screen, m_screens) { -- qCDebug(lcQpaScreen) << "adding" << screen << "(Primary:" << screen->isPrimary() << ")"; -- integration->screenAdded(screen, screen->isPrimary()); -- } -- -- if (!m_screens.isEmpty()) -- qCDebug(lcQpaScreen) << "primary output is" << m_screens.first()->name(); -+ // Push the screens to QGuiApplication -+ foreach (QXcbScreen *screen, m_screens) { -+ qCDebug(lcQpaScreen) << "adding" << screen << "(Primary:" << screen->isPrimary() << ")"; -+ QXcbIntegration::instance()->screenAdded(screen, screen->isPrimary()); -+ } -+ } - } - - QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGrabServer, xcb_visualid_t defaultVisualId, const char *displayName) -@@ -474,6 +487,7 @@ QXcbConnection::QXcbConnection(QXcbNativ - , m_canGrabServer(canGrabServer) - , m_defaultVisualId(defaultVisualId) - , m_primaryScreenNumber(0) -+ , m_onlyVirtualScreen(false) - , m_displayName(displayName ? QByteArray(displayName) : qgetenv("DISPLAY")) - , m_nativeInterface(nativeInterface) - #ifdef XCB_USE_XLIB -@@ -1110,8 +1124,19 @@ void QXcbConnection::handleXcbEvent(xcb_ - handled = false; - break; - case XCB_PROPERTY_NOTIFY: -- HANDLE_PLATFORM_WINDOW_EVENT(xcb_property_notify_event_t, window, handlePropertyNotifyEvent); -+ { -+ // Update geometry for all screens, because availableGeometry must be changed -+ const xcb_property_notify_event_t *propertyNotifyEvent = (const xcb_property_notify_event_t *)event; -+ if (propertyNotifyEvent->atom == atom(QXcbAtom::_NET_WORKAREA)) { -+ foreach (QXcbScreen *screen, m_screens) { -+ if (propertyNotifyEvent->window == screen->root()) -+ screen->updateGeometry(propertyNotifyEvent->time); -+ } -+ } 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 -rupN qtbase-opensource-src-5.5.1/src/plugins/platforms/xcb/qxcbconnection.h qtbase-opensource-src-5.5.1-new/src/plugins/platforms/xcb/qxcbconnection.h ---- qtbase-opensource-src-5.5.1/src/plugins/platforms/xcb/qxcbconnection.h 2015-10-13 06:35:27.000000000 +0200 -+++ qtbase-opensource-src-5.5.1-new/src/plugins/platforms/xcb/qxcbconnection.h 2015-10-21 21:00:21.767613360 +0200 -@@ -519,6 +519,9 @@ private: - QXcbVirtualDesktop* virtualDesktopForRootWindow(xcb_window_t rootWindow); - bool checkOutputIsPrimary(xcb_window_t rootWindow, xcb_randr_output_t output); - void initializeScreens(); -+ void destroyScreen(QXcbScreen *screen, bool canCreateVirtualScreen); -+ void createVirtualScreen(); -+ void maybeSetScreenForTopLevelWindows(QXcbScreen *screen); - void updateScreens(const xcb_randr_notify_event_t *event); - - bool m_xi2Enabled; -@@ -583,6 +586,7 @@ private: - QList m_virtualDesktops; - QList m_screens; - int m_primaryScreenNumber; -+ bool m_onlyVirtualScreen; - - xcb_atom_t m_allAtoms[QXcbAtom::NAtoms]; - -diff -rupN qtbase-opensource-src-5.5.1/src/plugins/platforms/xcb/qxcbscreen.cpp qtbase-opensource-src-5.5.1-new/src/plugins/platforms/xcb/qxcbscreen.cpp ---- qtbase-opensource-src-5.5.1/src/plugins/platforms/xcb/qxcbscreen.cpp 2015-10-13 06:35:27.000000000 +0200 -+++ qtbase-opensource-src-5.5.1-new/src/plugins/platforms/xcb/qxcbscreen.cpp 2015-10-21 21:00:21.768613377 +0200 -@@ -438,14 +438,6 @@ void QXcbScreen::handleScreenChange(xcb_ - - QDpi ldpi = logicalDpi(); - QWindowSystemInterface::handleScreenLogicalDotsPerInchChange(QPlatformScreen::screen(), ldpi.first, ldpi.second); -- -- // Windows which had null screens have already had expose events by now. -- // They need to be told the screen is back, it's OK to render. -- foreach (QWindow *window, QGuiApplication::topLevelWindows()) { -- QXcbWindow *xcbWin = static_cast(window->handle()); -- if (xcbWin) -- xcbWin->maybeSetScreen(this); -- } - } - - void QXcbScreen::updateGeometry(xcb_timestamp_t timestamp) -diff -rupN qtbase-opensource-src-5.5.1/src/plugins/platforms/xcb/qxcbscreen.h qtbase-opensource-src-5.5.1-new/src/plugins/platforms/xcb/qxcbscreen.h ---- qtbase-opensource-src-5.5.1/src/plugins/platforms/xcb/qxcbscreen.h 2015-10-13 06:35:27.000000000 +0200 -+++ qtbase-opensource-src-5.5.1-new/src/plugins/platforms/xcb/qxcbscreen.h 2015-10-21 21:00:21.768613377 +0200 -@@ -116,6 +116,8 @@ public: - xcb_randr_crtc_t crtc() const { return m_crtc; } - xcb_randr_mode_t mode() const { return m_mode; } - -+ void setCrtc(xcb_randr_crtc_t crtc) { m_crtc = crtc; } -+ - void windowShown(QXcbWindow *window); - QString windowManagerName() const { return m_windowManagerName; } - bool syncRequestSupported() const { return m_syncRequestSupported; } -diff -rupN qtbase-opensource-src-5.5.1/src/plugins/platforms/xcb/qxcbwindow.cpp qtbase-opensource-src-5.5.1-new/src/plugins/platforms/xcb/qxcbwindow.cpp ---- qtbase-opensource-src-5.5.1/src/plugins/platforms/xcb/qxcbwindow.cpp 2015-10-13 06:35:27.000000000 +0200 -+++ qtbase-opensource-src-5.5.1-new/src/plugins/platforms/xcb/qxcbwindow.cpp 2015-10-21 21:01:17.324562601 +0200 -@@ -694,12 +694,17 @@ void QXcbWindow::destroy() - m_pendingSyncRequest->invalidate(); - } - --void QXcbWindow::maybeSetScreen(QXcbScreen *screen) -+bool QXcbWindow::maybeSetScreen(QXcbScreen *screen) - { -- if (!window()->screen() && screen->geometry().contains(geometry().topLeft())) { -+ // Every window must have a screen. Otherwise application can -+ // crash and the window contents are invisible e.g. in x11vnc. -+ if (!window()->screen()) { - QWindowSystemInterface::handleWindowScreenChanged(window(), static_cast(screen)->screen()); -- QWindowSystemInterface::handleExposeEvent(window(), QRegion(QRect(QPoint(0, 0), window()->size()))); -+ if (screen->geometry().contains(geometry().topLeft())) -+ QWindowSystemInterface::handleExposeEvent(window(), QRegion(QRect(QPoint(0, 0), window()->size()))); -+ return true; - } -+ return false; - } - - void QXcbWindow::setGeometry(const QRect &rect) -@@ -1243,8 +1248,6 @@ void QXcbWindow::changeNetWmState(bool s - event.data.data32[3] = 0; - event.data.data32[4] = 0; - -- if (!xcbScreen()) -- return; - Q_XCB_CALL(xcb_send_event(xcb_connection(), 0, xcbScreen()->root(), XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, (const char *)&event)); - } - -@@ -1493,8 +1496,6 @@ void QXcbWindow::setParent(const QPlatfo - xcb_parent_id = qXcbParent->xcb_window(); - m_embedded = qXcbParent->window()->type() == Qt::ForeignWindow; - } else { -- if (!xcbScreen()) -- return; - xcb_parent_id = xcbScreen()->root(); - m_embedded = false; - } -@@ -2323,8 +2324,6 @@ void QXcbWindow::handleEnterNotifyEvent( - - const int dpr = int(devicePixelRatio()); - const QPoint local(event->event_x/dpr, event->event_y/dpr); -- if (!xcbScreen()) -- return; - QPoint global = xcbScreen()->mapFromNative(QPoint(event->root_x, event->root_y)); - QWindowSystemInterface::handleEnterEvent(window(), local, global); - } -@@ -2343,8 +2342,6 @@ void QXcbWindow::handleLeaveNotifyEvent( - if (enterWindow) { - const int dpr = int(devicePixelRatio()); - QPoint local(enter->event_x/dpr, enter->event_y/dpr); -- if (!xcbScreen()) -- return; - QPoint global = xcbScreen()->mapFromNative(QPoint(event->root_x, event->root_y)); - - QWindowSystemInterface::handleEnterLeaveEvent(enterWindow->window(), window(), local, global); -@@ -2360,8 +2357,6 @@ void QXcbWindow::handlePropertyNotifyEve - connection()->setTime(event->time); - - const bool propertyDeleted = event->state == XCB_PROPERTY_DELETE; -- if (!xcbScreen()) -- return; - - if (event->atom == atom(QXcbAtom::_NET_WM_STATE) || event->atom == atom(QXcbAtom::WM_STATE)) { - if (propertyDeleted) -@@ -2403,8 +2398,6 @@ void QXcbWindow::handlePropertyNotifyEve - 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); - } - } - -@@ -2682,8 +2675,6 @@ bool QXcbWindow::needsSync() const - - void QXcbWindow::postSyncWindowRequest() - { -- if (!xcbScreen()) -- return; - if (!m_pendingSyncRequest) { - QXcbSyncWindowRequest *e = new QXcbSyncWindowRequest(this); - m_pendingSyncRequest = e; -diff -rupN qtbase-opensource-src-5.5.1/src/plugins/platforms/xcb/qxcbwindow.h qtbase-opensource-src-5.5.1-new/src/plugins/platforms/xcb/qxcbwindow.h ---- qtbase-opensource-src-5.5.1/src/plugins/platforms/xcb/qxcbwindow.h 2015-10-13 06:35:27.000000000 +0200 -+++ qtbase-opensource-src-5.5.1-new/src/plugins/platforms/xcb/qxcbwindow.h 2015-10-21 21:00:21.769613394 +0200 -@@ -158,7 +158,7 @@ public: - - virtual void create(); - virtual void destroy(); -- void maybeSetScreen(QXcbScreen *screen); -+ bool maybeSetScreen(QXcbScreen *screen); - QXcbScreen *screenForNativeGeometry(const QRect &newGeometry) const; - - public Q_SLOTS: From 7a8506bfbcd3dbf31fdc08627c2aa10570b13493 Mon Sep 17 00:00:00 2001 From: Rex Dieter Date: Fri, 11 Dec 2015 22:46:03 -0600 Subject: [PATCH 2/3] sync latest xcb/screen/display related upstream commits --- 0001-XCB-prevent-a-fp-division-by-zero.patch | 58 ++ ...revious-state-when-sending-geometry-.patch | 86 +++ ...-Don-t-cache-the-screen-for-a-window.patch | 116 +++ ...older-QScreen-when-there-are-no-outp.patch | 721 ++++++++++++++++++ qt5-qtbase.spec | 21 +- 5 files changed, 995 insertions(+), 7 deletions(-) create mode 100644 0001-XCB-prevent-a-fp-division-by-zero.patch create mode 100644 0002-xcb-compare-to-previous-state-when-sending-geometry-.patch create mode 100644 0011-xcb-Don-t-cache-the-screen-for-a-window.patch create mode 100644 0012-xcb-Use-a-placeholder-QScreen-when-there-are-no-outp.patch diff --git a/0001-XCB-prevent-a-fp-division-by-zero.patch b/0001-XCB-prevent-a-fp-division-by-zero.patch new file mode 100644 index 0000000..9a186ab --- /dev/null +++ b/0001-XCB-prevent-a-fp-division-by-zero.patch @@ -0,0 +1,58 @@ +From 40c927e7331ea4ac9ca50de48560b700e657cded Mon Sep 17 00:00:00 2001 +From: Giuseppe D'Angelo +Date: Tue, 8 Dec 2015 18:28:24 +0100 +Subject: [PATCH 01/12] XCB: prevent a fp division by zero +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +For certain devices vci->resolution is zero, which causes a SIGFPE +if FE_INVALID exceptions are enabled. Try to prevent that. + +Task-number: QTBUG-42717 +Change-Id: I388735f5dfb6218496787dbb74cf0c0f43cc928f +Reviewed-by: Alexander Volkov +Reviewed-by: Błażej Szczygieł +Reviewed-by: Shawn Rutledge +--- + src/plugins/platforms/xcb/qxcbconnection_xi2.cpp | 11 +++++++---- + 1 file changed, 7 insertions(+), 4 deletions(-) + +diff --git a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp +index 8097cce..1a12370 100644 +--- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp ++++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp +@@ -406,6 +406,9 @@ XInput2TouchDeviceData *QXcbConnection::touchDeviceForId(int id) + #endif // XCB_USE_XINPUT22 + case XIValuatorClass: { + XIValuatorClassInfo *vci = reinterpret_cast(classinfo); ++ // Some devices (mice) report a resolution of 0; they will be excluded later, ++ // for now just prevent a division by zero ++ const int vciResolution = vci->resolution ? vci->resolution : 1; + if (vci->label == atom(QXcbAtom::AbsMTPositionX)) + caps |= QTouchDevice::Position | QTouchDevice::NormalizedPosition; + else if (vci->label == atom(QXcbAtom::AbsMTTouchMajor)) +@@ -414,16 +417,16 @@ XInput2TouchDeviceData *QXcbConnection::touchDeviceForId(int id) + caps |= QTouchDevice::Pressure; + else if (vci->label == atom(QXcbAtom::RelX)) { + hasRelativeCoords = true; +- dev->size.setWidth((vci->max - vci->min) * 1000.0 / vci->resolution); ++ dev->size.setWidth((vci->max - vci->min) * 1000.0 / vciResolution); + } else if (vci->label == atom(QXcbAtom::RelY)) { + hasRelativeCoords = true; +- dev->size.setHeight((vci->max - vci->min) * 1000.0 / vci->resolution); ++ dev->size.setHeight((vci->max - vci->min) * 1000.0 / vciResolution); + } else if (vci->label == atom(QXcbAtom::AbsX)) { + caps |= QTouchDevice::Position; +- dev->size.setHeight((vci->max - vci->min) * 1000.0 / vci->resolution); ++ dev->size.setHeight((vci->max - vci->min) * 1000.0 / vciResolution); + } else if (vci->label == atom(QXcbAtom::AbsY)) { + caps |= QTouchDevice::Position; +- dev->size.setWidth((vci->max - vci->min) * 1000.0 / vci->resolution); ++ dev->size.setWidth((vci->max - vci->min) * 1000.0 / vciResolution); + } + break; + } +-- +2.5.0 + diff --git a/0002-xcb-compare-to-previous-state-when-sending-geometry-.patch b/0002-xcb-compare-to-previous-state-when-sending-geometry-.patch new file mode 100644 index 0000000..2c74c52 --- /dev/null +++ b/0002-xcb-compare-to-previous-state-when-sending-geometry-.patch @@ -0,0 +1,86 @@ +From 56f6252e7285c9c61a99416fa2a8571fd67c597f Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= + +Date: Tue, 1 Dec 2015 16:27:09 +0100 +Subject: [PATCH 02/12] xcb: compare to previous state when sending geometry + and expose events +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +By calculating the previous geometry and passing it on when calling +handleGeometryChange we can detect cases where setGeometry() on a +QWindow didn't result in the expected geometry. The new (actual) +geometry is delivered as a resize event. + +This also allows us to only send expose events when the size of the +window has actually changed (instead of also sending when the window +has just moved). + +Due to the async delivery of geometry changes on the xcb platform we +need to avoid using QWindowPrivate's cached state of the geometry, as +that will result in duplicate resize events when events are not flushed +in between two system resize events coming in with the same size. + +Change-Id: I3d4abe4a1095dd96e6e354288d5b646c623c30dd +Reviewed-by: Tor Arne Vestbø +--- + src/plugins/platforms/xcb/qxcbwindow.cpp | 33 ++++++++++++++++++++++++++------ + 1 file changed, 27 insertions(+), 6 deletions(-) + +diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp +index 6023ee6..98bcc62 100644 +--- a/src/plugins/platforms/xcb/qxcbwindow.cpp ++++ b/src/plugins/platforms/xcb/qxcbwindow.cpp +@@ -2007,21 +2007,42 @@ void QXcbWindow::handleConfigureNotifyEvent(const xcb_configure_notify_event_t * + } + } + +- const QRect rect = QRect(pos, QSize(event->width, event->height)); +- QPlatformScreen *newScreen = parent() ? parent()->screen() : screenForGeometry(rect); ++ // The original geometry requested by setGeometry() might be different ++ // from what we end up with after applying window constraints. ++ QRect requestedGeometry = geometry(); ++ ++ const QRect actualGeometry = QRect(pos, QSize(event->width, event->height)); ++ QPlatformScreen *newScreen = parent() ? parent()->screen() : screenForGeometry(actualGeometry); + + QXcbScreen *currentScreen = m_xcbScreen; + m_xcbScreen = static_cast(newScreen); + if (!newScreen) + return; + +- QPlatformWindow::setGeometry(rect); +- QWindowSystemInterface::handleGeometryChange(window(), rect); ++ // Persist the actual geometry so that QWindow::geometry() can ++ // be queried in the resize event. ++ QPlatformWindow::setGeometry(actualGeometry); ++ ++ // As we're delivering the geometry change through QPA in n async fashion we can't ++ // pass on the current geometry of the QWindowPrivate, as that may have not been ++ // updated yet by a geometry change that's still in the QPA event queue. Instead ++ // we fall back to the default argument value of QRect(), which will result in ++ // QGuiApplication looking up the previous geometry from QWindowPrivate, but this ++ // time in sync with the even delivery/processing. ++ QWindowSystemInterface::handleGeometryChange(window(), actualGeometry, ++ requestedGeometry != actualGeometry ? requestedGeometry : QRect()); ++ + if (newScreen != currentScreen) + QWindowSystemInterface::handleWindowScreenChanged(window(), newScreen->screen()); + +- if (m_mapped) +- QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(), geometry().size())); ++ // For expose events we have no way of telling QGuiApplication to used the locally ++ // cached version of the previous state, so we may in some situations end up with ++ // an additional expose event. ++ QRect previousGeometry = requestedGeometry != actualGeometry ? ++ requestedGeometry : qt_window_private(window())->geometry; ++ ++ if (m_mapped && actualGeometry.size() != previousGeometry.size()) ++ QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(), actualGeometry.size())); + + if (m_usingSyncProtocol && m_syncState == SyncReceived) + m_syncState = SyncAndConfigureReceived; +-- +2.5.0 + diff --git a/0011-xcb-Don-t-cache-the-screen-for-a-window.patch b/0011-xcb-Don-t-cache-the-screen-for-a-window.patch new file mode 100644 index 0000000..fdd795e --- /dev/null +++ b/0011-xcb-Don-t-cache-the-screen-for-a-window.patch @@ -0,0 +1,116 @@ +From 0c33a823c560bdf18a513ae460eea4d7bdf9e115 Mon Sep 17 00:00:00 2001 +From: Alexander Volkov +Date: Tue, 24 Nov 2015 15:09:41 +0300 +Subject: [PATCH 11/12] xcb: Don't cache the screen for a window +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +QXcbWindow::m_xcbScreen was introduced in 4e1b09fa8ff1a9ab42c0a29a2efe1ae7f4700d71 +(Keep screen geometries from overlapping) to map the window +geometry for the right screen, because it wasn't possible to +rely on QPlatformWindow::screen(). + +But we don't need it since a705b4ec1f6f7133390054f8b6b8077ef0550311 +(Introduce cross platform high-dpi scaling), because QGuiApplication +triggers GeometryChangeEvent right after processing WindowScreenChangedEvent. + +So just use QPlatformWindow::screen() instead of cached m_xcbScreen. + +m_xcbScreen was also used in d4bc56cb4218f6f8378f04c23865156b349b037d +(Fix screen detection on configureNotify) to compare the new screen +after receiving ConfigureNotify to the correct old screen. Just send +WindowScreenChangedEvent event and leave making the comparison to +QGuiApplication. + +Change-Id: Ibe717ae4bf4c40b0a04cd62fe2ecaee5df5f4060 +Reviewed-by: Błażej Szczygieł +Reviewed-by: Shawn Rutledge +--- + src/plugins/platforms/xcb/qxcbwindow.cpp | 16 ++++++---------- + src/plugins/platforms/xcb/qxcbwindow.h | 2 -- + 2 files changed, 6 insertions(+), 12 deletions(-) + +diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp +index 98bcc62..6add0a6 100644 +--- a/src/plugins/platforms/xcb/qxcbwindow.cpp ++++ b/src/plugins/platforms/xcb/qxcbwindow.cpp +@@ -143,7 +143,7 @@ const quint32 XEMBED_VERSION = 0; + + QXcbScreen *QXcbWindow::parentScreen() + { +- return parent() ? static_cast(parent())->parentScreen() : m_xcbScreen; ++ return parent() ? static_cast(parent())->parentScreen() : xcbScreen(); + } + + // Returns \c true if we should set WM_TRANSIENT_FOR on \a w +@@ -266,7 +266,6 @@ static const char *wm_window_type_property_id = "_q_xcb_wm_window_type"; + QXcbWindow::QXcbWindow(QWindow *window) + : QPlatformWindow(window) + , m_window(0) +- , m_xcbScreen(0) + , m_syncCounter(0) + , m_gravity(XCB_GRAVITY_STATIC) + , m_mapped(false) +@@ -322,7 +321,6 @@ void QXcbWindow::create() + QRect rect = windowGeometry(); + QXcbScreen *platformScreen = parent() ? parentScreen() : static_cast(screenForGeometry(rect)); + +- m_xcbScreen = platformScreen; + if (type == Qt::Desktop) { + m_window = platformScreen->root(); + m_depth = platformScreen->screen()->root_depth; +@@ -638,13 +636,12 @@ void QXcbWindow::setGeometry(const QRect &rect) + + propagateSizeHints(); + +- QXcbScreen *currentScreen = m_xcbScreen; ++ QXcbScreen *currentScreen = xcbScreen(); + QXcbScreen *newScreen = parent() ? parentScreen() : static_cast(screenForGeometry(rect)); + + if (!newScreen) + newScreen = xcbScreen(); + +- m_xcbScreen = newScreen; + const QRect wmGeometry = windowToWmGeometry(rect); + + if (newScreen && newScreen != currentScreen) +@@ -2013,9 +2010,6 @@ void QXcbWindow::handleConfigureNotifyEvent(const xcb_configure_notify_event_t * + + const QRect actualGeometry = QRect(pos, QSize(event->width, event->height)); + QPlatformScreen *newScreen = parent() ? parent()->screen() : screenForGeometry(actualGeometry); +- +- QXcbScreen *currentScreen = m_xcbScreen; +- m_xcbScreen = static_cast(newScreen); + if (!newScreen) + return; + +@@ -2032,8 +2026,10 @@ void QXcbWindow::handleConfigureNotifyEvent(const xcb_configure_notify_event_t * + QWindowSystemInterface::handleGeometryChange(window(), actualGeometry, + requestedGeometry != actualGeometry ? requestedGeometry : QRect()); + +- if (newScreen != currentScreen) +- QWindowSystemInterface::handleWindowScreenChanged(window(), newScreen->screen()); ++ // QPlatformScreen::screen() is updated asynchronously, so we can't compare it ++ // with the newScreen. Just send the WindowScreenChanged event and QGuiApplication ++ // will make the comparison later. ++ QWindowSystemInterface::handleWindowScreenChanged(window(), newScreen->screen()); + + // For expose events we have no way of telling QGuiApplication to used the locally + // cached version of the previous state, so we may in some situations end up with +diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h +index 43e66a7..0d14673 100644 +--- a/src/plugins/platforms/xcb/qxcbwindow.h ++++ b/src/plugins/platforms/xcb/qxcbwindow.h +@@ -214,8 +214,6 @@ protected: + + xcb_window_t m_window; + +- QXcbScreen *m_xcbScreen; +- + uint m_depth; + QImage::Format m_imageFormat; + bool m_imageRgbSwap; +-- +2.5.0 + diff --git a/0012-xcb-Use-a-placeholder-QScreen-when-there-are-no-outp.patch b/0012-xcb-Use-a-placeholder-QScreen-when-there-are-no-outp.patch new file mode 100644 index 0000000..665827e --- /dev/null +++ b/0012-xcb-Use-a-placeholder-QScreen-when-there-are-no-outp.patch @@ -0,0 +1,721 @@ +From a094af001795c9651b299d700a992150d1aba33a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?B=C5=82a=C5=BCej=20Szczygie=C5=82?= +Date: Fri, 16 Oct 2015 22:51:59 +0200 +Subject: [PATCH 12/12] xcb: Use a placeholder QScreen when there are no + outputs connected + +If no screens are available, windows could disappear, could stop rendering +graphics, or the application could crash. This is a real use case in several +scenarios: with x11vnc, when all monitors are physically disconnected from a +desktop machine, or in some cases even when the monitor sleeps. Now when the +last screen is disconnected, it is transformed into a fake screen. When a +physical screen appears, the fake QScreen is transformed into a representation +of the physical screen. Every virtual desktop has its own fake screen, and +primary screens must belong to the primary virtual desktop. It fixes updating +screen geometry on temporarily disabled screens in the middle of the mode +switch. + +Expected results: Windows don't disappear, the application doesn't +crash, and QMenu is displayed on the appropriate screen. + +This reverts patch 51ada7734ad780178ecced11e0dff454dfc2e5f2 + +Change-Id: I6e8eb682b0c8425d08ffdaecbd4c6c7700c914b4 +Task-number: QTBUG-42985 +Reviewed-by: Shawn Rutledge +--- + src/gui/kernel/qscreen.cpp | 4 +- + src/plugins/platforms/xcb/qxcbconnection.cpp | 273 +++++++++++++++------------ + src/plugins/platforms/xcb/qxcbconnection.h | 10 +- + src/plugins/platforms/xcb/qxcbscreen.cpp | 49 +++-- + src/plugins/platforms/xcb/qxcbscreen.h | 10 +- + src/plugins/platforms/xcb/qxcbwindow.cpp | 38 +--- + src/plugins/platforms/xcb/qxcbwindow.h | 1 - + 7 files changed, 212 insertions(+), 173 deletions(-) + +diff --git a/src/gui/kernel/qscreen.cpp b/src/gui/kernel/qscreen.cpp +index fb322ae..52e7686 100644 +--- a/src/gui/kernel/qscreen.cpp ++++ b/src/gui/kernel/qscreen.cpp +@@ -116,8 +116,8 @@ QScreen::~QScreen() + bool movingFromVirtualSibling = primaryScreen && primaryScreen->handle()->virtualSiblings().contains(handle()); + + // Move any leftover windows to the primary screen +- foreach (QWindow *window, QGuiApplication::topLevelWindows()) { +- if (window->screen() != this) ++ foreach (QWindow *window, QGuiApplication::allWindows()) { ++ if (!window->isTopLevel() || window->screen() != this) + continue; + + const bool wasVisible = window->isVisible(); +diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp +index 50d49ca..231fe9a 100644 +--- a/src/plugins/platforms/xcb/qxcbconnection.cpp ++++ b/src/plugins/platforms/xcb/qxcbconnection.cpp +@@ -179,42 +179,6 @@ QXcbScreen* QXcbConnection::findScreenForOutput(xcb_window_t rootWindow, xcb_ran + return 0; + } + +-QXcbScreen* QXcbConnection::createScreen(QXcbVirtualDesktop* virtualDesktop, +- xcb_randr_output_t outputId, +- xcb_randr_get_output_info_reply_t *output) +-{ +- QString name; +- if (output) +- name = QString::fromUtf8((const char*)xcb_randr_get_output_info_name(output), +- xcb_randr_get_output_info_name_length(output)); +- else { +- QByteArray displayName = m_displayName; +- int dotPos = displayName.lastIndexOf('.'); +- if (dotPos != -1) +- displayName.truncate(dotPos); +- name = QString::fromLocal8Bit(displayName) + QLatin1Char('.') + QString::number(virtualDesktop->number()); +- } +- +- return new QXcbScreen(this, virtualDesktop, outputId, output, name); +-} +- +-bool QXcbConnection::checkOutputIsPrimary(xcb_window_t rootWindow, xcb_randr_output_t output) +-{ +- xcb_generic_error_t *error = 0; +- xcb_randr_get_output_primary_cookie_t primaryCookie = +- xcb_randr_get_output_primary(xcb_connection(), rootWindow); +- QScopedPointer primary ( +- xcb_randr_get_output_primary_reply(xcb_connection(), primaryCookie, &error)); +- if (!primary || error) { +- qWarning("failed to get the primary output of the screen"); +- free(error); +- error = NULL; +- } +- const bool isPrimary = primary ? (primary->output == output) : false; +- +- return isPrimary; +-} +- + QXcbVirtualDesktop* QXcbConnection::virtualDesktopForRootWindow(xcb_window_t rootWindow) + { + foreach (QXcbVirtualDesktop *virtualDesktop, m_virtualDesktops) { +@@ -237,8 +201,9 @@ void QXcbConnection::updateScreens(const xcb_randr_notify_event_t *event) + // Not for us + return; + +- qCDebug(lcQpaScreen) << "QXcbConnection: XCB_RANDR_NOTIFY_CRTC_CHANGE:" << crtc.crtc; + QXcbScreen *screen = findScreenForCrtc(crtc.window, crtc.crtc); ++ qCDebug(lcQpaScreen) << "QXcbConnection: XCB_RANDR_NOTIFY_CRTC_CHANGE:" << crtc.crtc ++ << "mode" << crtc.mode << "relevant screen" << screen; + // Only update geometry when there's a valid mode on the CRTC + // CRTC with node mode could mean that output has been disabled, and we'll + // get RRNotifyOutputChange notification for that. +@@ -260,16 +225,7 @@ void QXcbConnection::updateScreens(const xcb_randr_notify_event_t *event) + + if (screen && output.connection == XCB_RANDR_CONNECTION_DISCONNECTED) { + qCDebug(lcQpaScreen) << "screen" << screen->name() << "has been disconnected"; +- +- // Known screen removed -> delete it +- m_screens.removeOne(screen); +- virtualDesktop->removeScreen(screen); +- +- QXcbIntegration::instance()->destroyScreen(screen); +- +- // QTBUG-40174, QTBUG-42985: If all screens are removed, wait +- // and start rendering again later if a screen becomes available. +- ++ destroyScreen(screen); + } else if (!screen && output.connection == XCB_RANDR_CONNECTION_CONNECTED) { + // New XRandR output is available and it's enabled + if (output.crtc != XCB_NONE && output.mode != XCB_NONE) { +@@ -278,59 +234,142 @@ void QXcbConnection::updateScreens(const xcb_randr_notify_event_t *event) + QScopedPointer outputInfo( + xcb_randr_get_output_info_reply(xcb_connection(), outputInfoCookie, NULL)); + +- screen = createScreen(virtualDesktop, output.output, outputInfo.data()); +- qCDebug(lcQpaScreen) << "output" << screen->name() << "is connected and enabled"; +- +- screen->setPrimary(checkOutputIsPrimary(output.window, output.output)); +- virtualDesktop->addScreen(screen); +- m_screens << screen; +- QXcbIntegration::instance()->screenAdded(screen, screen->isPrimary()); ++ // Find a fake screen ++ foreach (QPlatformScreen *scr, virtualDesktop->screens()) { ++ QXcbScreen *xcbScreen = (QXcbScreen *)scr; ++ if (xcbScreen->output() == XCB_NONE) { ++ screen = xcbScreen; ++ break; ++ } ++ } + +- // Windows which had null screens have already had expose events by now. +- // They need to be told the screen is back, it's OK to render. +- foreach (QWindow *window, QGuiApplication::topLevelWindows()) { +- QXcbWindow *xcbWin = static_cast(window->handle()); +- if (xcbWin) +- xcbWin->maybeSetScreen(screen); ++ if (screen) { ++ QString nameWas = screen->name(); ++ // Transform the fake screen into a physical screen ++ screen->setOutput(output.output, outputInfo.data()); ++ updateScreen(screen, output); ++ qCDebug(lcQpaScreen) << "output" << screen->name() ++ << "is connected and enabled; was fake:" << nameWas; ++ } else { ++ screen = createScreen(virtualDesktop, output, outputInfo.data()); ++ qCDebug(lcQpaScreen) << "output" << screen->name() << "is connected and enabled"; + } + } +- // else ignore disabled screens + } else if (screen) { +- // Screen has been disabled -> remove + if (output.crtc == XCB_NONE && output.mode == XCB_NONE) { ++ // Screen has been disabled + xcb_randr_get_output_info_cookie_t outputInfoCookie = + xcb_randr_get_output_info(xcb_connection(), output.output, output.config_timestamp); + QScopedPointer outputInfo( + xcb_randr_get_output_info_reply(xcb_connection(), outputInfoCookie, NULL)); + if (outputInfo->crtc == XCB_NONE) { + qCDebug(lcQpaScreen) << "output" << screen->name() << "has been disabled"; +- m_screens.removeOne(screen); +- virtualDesktop->removeScreen(screen); +- QXcbIntegration::instance()->destroyScreen(screen); ++ destroyScreen(screen); + } else { + qCDebug(lcQpaScreen) << "output" << screen->name() << "has been temporarily disabled for the mode switch"; ++ // Reset crtc to skip RRCrtcChangeNotify events, ++ // because they may be invalid in the middle of the mode switch ++ screen->setCrtc(XCB_NONE); + } + } else { +- // Just update existing screen +- screen->updateGeometry(output.config_timestamp); +- const bool wasPrimary = screen->isPrimary(); +- screen->setPrimary(checkOutputIsPrimary(output.window, output.output)); +- if (screen->mode() != output.mode) +- screen->updateRefreshRate(output.mode); +- +- // If the screen became primary, reshuffle the order in QGuiApplicationPrivate +- if (!wasPrimary && screen->isPrimary()) { +- const int idx = m_screens.indexOf(screen); +- m_screens.swap(0, idx); +- QXcbIntegration::instance()->setPrimaryScreen(screen); +- } ++ updateScreen(screen, output); + qCDebug(lcQpaScreen) << "output has changed" << screen; + } + } ++ ++ qCDebug(lcQpaScreen) << "primary output is" << m_screens.first()->name(); ++ } ++} ++ ++bool QXcbConnection::checkOutputIsPrimary(xcb_window_t rootWindow, xcb_randr_output_t output) ++{ ++ xcb_generic_error_t *error = 0; ++ xcb_randr_get_output_primary_cookie_t primaryCookie = ++ xcb_randr_get_output_primary(xcb_connection(), rootWindow); ++ QScopedPointer primary ( ++ xcb_randr_get_output_primary_reply(xcb_connection(), primaryCookie, &error)); ++ if (!primary || error) { ++ qWarning("failed to get the primary output of the screen"); ++ free(error); ++ error = NULL; ++ } ++ const bool isPrimary = primary ? (primary->output == output) : false; ++ ++ return isPrimary; ++} ++ ++void QXcbConnection::updateScreen(QXcbScreen *screen, const xcb_randr_output_change_t &outputChange) ++{ ++ screen->setCrtc(outputChange.crtc); // Set the new crtc, because it can be invalid ++ screen->updateGeometry(outputChange.config_timestamp); ++ if (screen->mode() != outputChange.mode) ++ screen->updateRefreshRate(outputChange.mode); ++ // Only screen which belongs to the primary virtual desktop can be a primary screen ++ if (screen->screenNumber() == m_primaryScreenNumber) { ++ if (!screen->isPrimary() && checkOutputIsPrimary(outputChange.window, outputChange.output)) { ++ screen->setPrimary(true); ++ ++ // If the screen became primary, reshuffle the order in QGuiApplicationPrivate ++ const int idx = m_screens.indexOf(screen); ++ if (idx > 0) { ++ m_screens.first()->setPrimary(false); ++ m_screens.swap(0, idx); ++ } ++ screen->virtualDesktop()->setPrimaryScreen(screen); ++ QXcbIntegration::instance()->setPrimaryScreen(screen); ++ } ++ } ++} ++ ++QXcbScreen *QXcbConnection::createScreen(QXcbVirtualDesktop *virtualDesktop, ++ const xcb_randr_output_change_t &outputChange, ++ xcb_randr_get_output_info_reply_t *outputInfo) ++{ ++ QXcbScreen *screen = new QXcbScreen(this, virtualDesktop, outputChange.output, outputInfo); ++ // Only screen which belongs to the primary virtual desktop can be a primary screen ++ if (screen->screenNumber() == m_primaryScreenNumber) ++ screen->setPrimary(checkOutputIsPrimary(outputChange.window, outputChange.output)); ++ ++ if (screen->isPrimary()) { + if (!m_screens.isEmpty()) +- qCDebug(lcQpaScreen) << "primary output is" << m_screens.first()->name(); +- else +- qCDebug(lcQpaScreen) << "no outputs"; ++ m_screens.first()->setPrimary(false); ++ ++ m_screens.prepend(screen); ++ } else { ++ m_screens.append(screen); ++ } ++ virtualDesktop->addScreen(screen); ++ QXcbIntegration::instance()->screenAdded(screen, screen->isPrimary()); ++ ++ return screen; ++} ++ ++void QXcbConnection::destroyScreen(QXcbScreen *screen) ++{ ++ QXcbVirtualDesktop *virtualDesktop = screen->virtualDesktop(); ++ if (virtualDesktop->screens().count() == 1) { ++ // If there are no other screens on the same virtual desktop, ++ // then transform the physical screen into a fake screen. ++ const QString nameWas = screen->name(); ++ screen->setOutput(XCB_NONE, Q_NULLPTR); ++ qCDebug(lcQpaScreen) << "transformed" << nameWas << "to fake" << screen; ++ } else { ++ // There is more than one screen on the same virtual desktop, remove the screen ++ m_screens.removeOne(screen); ++ virtualDesktop->removeScreen(screen); ++ ++ // When primary screen is removed, set the new primary screen ++ // which belongs to the primary virtual desktop. ++ if (screen->isPrimary()) { ++ QXcbScreen *newPrimary = (QXcbScreen *)virtualDesktop->screens().at(0); ++ newPrimary->setPrimary(true); ++ const int idx = m_screens.indexOf(newPrimary); ++ if (idx > 0) ++ m_screens.swap(0, idx); ++ QXcbIntegration::instance()->setPrimaryScreen(newPrimary); ++ } ++ ++ QXcbIntegration::instance()->destroyScreen(screen); + } + } + +@@ -338,8 +377,7 @@ void QXcbConnection::initializeScreens() + { + xcb_screen_iterator_t it = xcb_setup_roots_iterator(m_setup); + int xcbScreenNumber = 0; // screen number in the xcb sense +- QXcbScreen* primaryScreen = Q_NULLPTR; +- bool hasOutputs = false; ++ QXcbScreen *primaryScreen = Q_NULLPTR; + while (it.rem) { + // Each "screen" in xcb terminology is a virtual desktop, + // potentially a collection of separate juxtaposed monitors. +@@ -348,8 +386,6 @@ void QXcbConnection::initializeScreens() + xcb_screen_t *xcbScreen = it.data; + QXcbVirtualDesktop *virtualDesktop = new QXcbVirtualDesktop(this, xcbScreen, xcbScreenNumber); + m_virtualDesktops.append(virtualDesktop); +- QList siblings; +- int outputCount = 0; + if (has_randr_extension) { + xcb_generic_error_t *error = NULL; + // RRGetScreenResourcesCurrent is fast but it may return nothing if the +@@ -366,7 +402,7 @@ void QXcbConnection::initializeScreens() + } else { + xcb_timestamp_t timestamp; + xcb_randr_output_t *outputs = Q_NULLPTR; +- outputCount = xcb_randr_get_screen_resources_current_outputs_length(resources_current.data()); ++ int outputCount = xcb_randr_get_screen_resources_current_outputs_length(resources_current.data()); + if (outputCount) { + timestamp = resources_current->config_timestamp; + outputs = xcb_randr_get_screen_resources_current_outputs(resources_current.data()); +@@ -393,6 +429,7 @@ void QXcbConnection::initializeScreens() + qWarning("failed to get the primary output of the screen"); + free(error); + } else { ++ QList siblings; + for (int i = 0; i < outputCount; i++) { + QScopedPointer output( + xcb_randr_get_output_info_reply(xcb_connection(), +@@ -416,9 +453,8 @@ void QXcbConnection::initializeScreens() + continue; + } + +- QXcbScreen *screen = createScreen(virtualDesktop, outputs[i], output.data()); ++ QXcbScreen *screen = new QXcbScreen(this, virtualDesktop, outputs[i], output.data()); + siblings << screen; +- hasOutputs = true; + m_screens << screen; + + // There can be multiple outputs per screen, use either +@@ -435,11 +471,23 @@ void QXcbConnection::initializeScreens() + } + } + } ++ virtualDesktop->setScreens(siblings); + } + } + } + } +- virtualDesktop->setScreens(siblings); ++ if (virtualDesktop->screens().isEmpty()) { ++ // If there are no XRandR outputs or XRandR extension is missing, ++ // then create a fake/legacy screen. ++ QXcbScreen *screen = new QXcbScreen(this, virtualDesktop, XCB_NONE, Q_NULLPTR); ++ qCDebug(lcQpaScreen) << "created fake screen" << screen; ++ m_screens << screen; ++ if (m_primaryScreenNumber == xcbScreenNumber) { ++ primaryScreen = screen; ++ primaryScreen->setPrimary(true); ++ } ++ virtualDesktop->addScreen(screen); ++ } + xcb_screen_next(&it); + ++xcbScreenNumber; + } // for each xcb screen +@@ -447,39 +495,25 @@ void QXcbConnection::initializeScreens() + foreach (QXcbVirtualDesktop *virtualDesktop, m_virtualDesktops) + virtualDesktop->subscribeToXFixesSelectionNotify(); + +- // If there's no randr extension, or there was some error above, or we found a +- // screen which doesn't have outputs for some other reason (e.g. on VNC or ssh -X), +- // but the dimensions are known anyway, and we don't already have any lingering +- // (possibly disconnected) screens, then showing windows should be possible, +- // so create one screen. (QTBUG-31389) +- QXcbVirtualDesktop *virtualDesktop = m_virtualDesktops.value(0); +- if (virtualDesktop && !hasOutputs && !virtualDesktop->size().isEmpty() && m_screens.isEmpty()) { +- QXcbScreen *screen = createScreen(virtualDesktop, 0, Q_NULLPTR); +- virtualDesktop->setScreens(QList() << screen); +- m_screens << screen; +- primaryScreen = screen; +- primaryScreen->setPrimary(true); +- qCDebug(lcQpaScreen) << "found a screen with zero outputs" << screen; +- } +- +- // Ensure the primary screen is first in the list +- if (primaryScreen) { +- Q_ASSERT(!m_screens.isEmpty()); +- if (m_screens.first() != primaryScreen) { +- m_screens.removeOne(primaryScreen); +- m_screens.prepend(primaryScreen); ++ if (m_virtualDesktops.isEmpty()) { ++ qFatal("QXcbConnection: no screens available"); ++ } else { ++ // Ensure the primary screen is first on the list ++ if (primaryScreen) { ++ if (m_screens.first() != primaryScreen) { ++ m_screens.removeOne(primaryScreen); ++ m_screens.prepend(primaryScreen); ++ } + } +- } + +- // Push the screens to QApplication +- QXcbIntegration *integration = QXcbIntegration::instance(); +- foreach (QXcbScreen* screen, m_screens) { +- qCDebug(lcQpaScreen) << "adding" << screen << "(Primary:" << screen->isPrimary() << ')'; +- integration->screenAdded(screen, screen->isPrimary()); +- } ++ // Push the screens to QGuiApplication ++ foreach (QXcbScreen *screen, m_screens) { ++ qCDebug(lcQpaScreen) << "adding" << screen << "(Primary:" << screen->isPrimary() << ")"; ++ QXcbIntegration::instance()->screenAdded(screen, screen->isPrimary()); ++ } + +- if (!m_screens.isEmpty()) + qCDebug(lcQpaScreen) << "primary output is" << m_screens.first()->name(); ++ } + } + + QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGrabServer, xcb_visualid_t defaultVisualId, const char *displayName) +@@ -553,9 +587,6 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGra + initializeXFixes(); + initializeScreens(); + +- if (m_screens.isEmpty()) +- qFatal("QXcbConnection: no screens available"); +- + initializeXRender(); + m_xi2Enabled = false; + #if defined(XCB_USE_XINPUT2) +diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h +index 3c82170..fb7cc13 100644 +--- a/src/plugins/platforms/xcb/qxcbconnection.h ++++ b/src/plugins/platforms/xcb/qxcbconnection.h +@@ -518,15 +518,17 @@ private: + void initializeXShape(); + void initializeXKB(); + void handleClientMessageEvent(const xcb_client_message_event_t *event); +- QXcbScreen* createScreen(QXcbVirtualDesktop *virtualDesktop, +- xcb_randr_output_t outputId = XCB_NONE, +- xcb_randr_get_output_info_reply_t *output = 0); + QXcbScreen* findScreenForCrtc(xcb_window_t rootWindow, xcb_randr_crtc_t crtc); + QXcbScreen* findScreenForOutput(xcb_window_t rootWindow, xcb_randr_output_t output); + QXcbVirtualDesktop* virtualDesktopForRootWindow(xcb_window_t rootWindow); ++ void updateScreens(const xcb_randr_notify_event_t *event); + bool checkOutputIsPrimary(xcb_window_t rootWindow, xcb_randr_output_t output); ++ void updateScreen(QXcbScreen *screen, const xcb_randr_output_change_t &outputChange); ++ QXcbScreen *createScreen(QXcbVirtualDesktop *virtualDesktop, ++ const xcb_randr_output_change_t &outputChange, ++ xcb_randr_get_output_info_reply_t *outputInfo); ++ void destroyScreen(QXcbScreen *screen); + void initializeScreens(); +- void updateScreens(const xcb_randr_notify_event_t *event); + bool compressEvent(xcb_generic_event_t *event, int currentIndex, QXcbEventArray *eventqueue) const; + + bool m_xi2Enabled; +diff --git a/src/plugins/platforms/xcb/qxcbscreen.cpp b/src/plugins/platforms/xcb/qxcbscreen.cpp +index 0e99d58..f05432e 100644 +--- a/src/plugins/platforms/xcb/qxcbscreen.cpp ++++ b/src/plugins/platforms/xcb/qxcbscreen.cpp +@@ -81,6 +81,13 @@ void QXcbVirtualDesktop::addScreen(QPlatformScreen *s) + ((QXcbScreen *) s)->isPrimary() ? m_screens.prepend(s) : m_screens.append(s); + } + ++void QXcbVirtualDesktop::setPrimaryScreen(QPlatformScreen *s) ++{ ++ const int idx = m_screens.indexOf(s); ++ Q_ASSERT(idx > -1); ++ m_screens.swap(0, idx); ++} ++ + QXcbXSettings *QXcbVirtualDesktop::xSettings() const + { + if (!m_xSettings) { +@@ -149,16 +156,15 @@ void QXcbVirtualDesktop::updateWorkArea() + } + + QXcbScreen::QXcbScreen(QXcbConnection *connection, QXcbVirtualDesktop *virtualDesktop, +- xcb_randr_output_t outputId, xcb_randr_get_output_info_reply_t *output, +- QString outputName) ++ xcb_randr_output_t outputId, xcb_randr_get_output_info_reply_t *output) + : QXcbObject(connection) + , m_virtualDesktop(virtualDesktop) + , m_output(outputId) +- , m_crtc(output ? output->crtc : 0) ++ , m_crtc(output ? output->crtc : XCB_NONE) + , m_mode(XCB_NONE) + , m_primary(false) + , m_rotation(XCB_RANDR_ROTATION_ROTATE_0) +- , m_outputName(outputName) ++ , m_outputName(getOutputName(output)) + , m_outputSizeMillimeters(output ? QSize(output->mm_width, output->mm_height) : QSize()) + , m_virtualSize(virtualDesktop->size()) + , m_virtualSizeMillimeters(virtualDesktop->physicalSize()) +@@ -268,6 +274,22 @@ QXcbScreen::~QXcbScreen() + delete m_cursor; + } + ++QString QXcbScreen::getOutputName(xcb_randr_get_output_info_reply_t *outputInfo) ++{ ++ QString name; ++ if (outputInfo) { ++ name = QString::fromUtf8((const char*)xcb_randr_get_output_info_name(outputInfo), ++ xcb_randr_get_output_info_name_length(outputInfo)); ++ } else { ++ QByteArray displayName = connection()->displayName(); ++ int dotPos = displayName.lastIndexOf('.'); ++ if (dotPos != -1) ++ displayName.truncate(dotPos); ++ name = QString::fromLocal8Bit(displayName) + QLatin1Char('.') ++ + QString::number(m_virtualDesktop->number()); ++ } ++ return name; ++} + + QWindow *QXcbScreen::topLevelAt(const QPoint &p) const + { +@@ -392,6 +414,16 @@ QPlatformCursor *QXcbScreen::cursor() const + return m_cursor; + } + ++void QXcbScreen::setOutput(xcb_randr_output_t outputId, ++ xcb_randr_get_output_info_reply_t *outputInfo) ++{ ++ m_output = outputId; ++ m_crtc = outputInfo ? outputInfo->crtc : XCB_NONE; ++ m_mode = XCB_NONE; ++ m_outputName = getOutputName(outputInfo); ++ // TODO: Send an event to the QScreen instance that the screen changed its name ++} ++ + /*! + \brief handle the XCB screen change event and update properties + +@@ -460,19 +492,10 @@ void QXcbScreen::handleScreenChange(xcb_randr_screen_change_notify_event_t *chan + + updateGeometry(change_event->timestamp); + +- QWindowSystemInterface::handleScreenGeometryChange(QPlatformScreen::screen(), geometry(), availableGeometry()); + QWindowSystemInterface::handleScreenOrientationChange(QPlatformScreen::screen(), m_orientation); + + QDpi ldpi = logicalDpi(); + QWindowSystemInterface::handleScreenLogicalDotsPerInchChange(QPlatformScreen::screen(), ldpi.first, ldpi.second); +- +- // Windows which had null screens have already had expose events by now. +- // They need to be told the screen is back, it's OK to render. +- foreach (QWindow *window, QGuiApplication::topLevelWindows()) { +- QXcbWindow *xcbWin = static_cast(window->handle()); +- if (xcbWin) +- xcbWin->maybeSetScreen(this); +- } + } + + void QXcbScreen::updateGeometry(xcb_timestamp_t timestamp) +diff --git a/src/plugins/platforms/xcb/qxcbscreen.h b/src/plugins/platforms/xcb/qxcbscreen.h +index c68c290..79620f4 100644 +--- a/src/plugins/platforms/xcb/qxcbscreen.h ++++ b/src/plugins/platforms/xcb/qxcbscreen.h +@@ -72,6 +72,7 @@ public: + void setScreens(QList sl) { m_screens = sl; } + void removeScreen(QPlatformScreen *s) { m_screens.removeOne(s); } + void addScreen(QPlatformScreen *s); ++ void setPrimaryScreen(QPlatformScreen *s); + + QXcbXSettings *xSettings() const; + +@@ -101,10 +102,11 @@ class Q_XCB_EXPORT QXcbScreen : public QXcbObject, public QPlatformScreen + { + public: + QXcbScreen(QXcbConnection *connection, QXcbVirtualDesktop *virtualDesktop, +- xcb_randr_output_t outputId, xcb_randr_get_output_info_reply_t *output, +- QString outputName); ++ xcb_randr_output_t outputId, xcb_randr_get_output_info_reply_t *outputInfo); + ~QXcbScreen(); + ++ QString getOutputName(xcb_randr_get_output_info_reply_t *outputInfo); ++ + QPixmap grabWindow(WId window, int x, int y, int width, int height) const Q_DECL_OVERRIDE; + + QWindow *topLevelAt(const QPoint &point) const Q_DECL_OVERRIDE; +@@ -137,6 +139,10 @@ public: + xcb_randr_crtc_t crtc() const { return m_crtc; } + xcb_randr_mode_t mode() const { return m_mode; } + ++ void setOutput(xcb_randr_output_t outputId, ++ xcb_randr_get_output_info_reply_t *outputInfo); ++ void setCrtc(xcb_randr_crtc_t crtc) { m_crtc = crtc; } ++ + void windowShown(QXcbWindow *window); + QString windowManagerName() const { return m_windowManagerName; } + bool syncRequestSupported() const { return m_syncRequestSupported; } +diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp +index 6add0a6..bdbb9e9 100644 +--- a/src/plugins/platforms/xcb/qxcbwindow.cpp ++++ b/src/plugins/platforms/xcb/qxcbwindow.cpp +@@ -622,14 +622,6 @@ void QXcbWindow::destroy() + m_pendingSyncRequest->invalidate(); + } + +-void QXcbWindow::maybeSetScreen(QXcbScreen *screen) +-{ +- if (!window()->screen() && screen->geometry().contains(geometry().topLeft())) { +- QWindowSystemInterface::handleWindowScreenChanged(window(), static_cast(screen)->screen()); +- QWindowSystemInterface::handleExposeEvent(window(), QRegion(QRect(QPoint(0, 0), window()->size()))); +- } +-} +- + void QXcbWindow::setGeometry(const QRect &rect) + { + QPlatformWindow::setGeometry(rect); +@@ -845,15 +837,13 @@ void QXcbWindow::hide() + Q_XCB_CALL(xcb_unmap_window(xcb_connection(), m_window)); + + // send synthetic UnmapNotify event according to icccm 4.1.4 +- if (xcbScreen()) { +- xcb_unmap_notify_event_t event; +- event.response_type = XCB_UNMAP_NOTIFY; +- event.event = xcbScreen()->root(); +- event.window = m_window; +- event.from_configure = false; +- Q_XCB_CALL(xcb_send_event(xcb_connection(), false, xcbScreen()->root(), +- XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, (const char *)&event)); +- } ++ xcb_unmap_notify_event_t event; ++ event.response_type = XCB_UNMAP_NOTIFY; ++ event.event = xcbScreen()->root(); ++ event.window = m_window; ++ event.from_configure = false; ++ Q_XCB_CALL(xcb_send_event(xcb_connection(), false, xcbScreen()->root(), ++ XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, (const char *)&event)); + + xcb_flush(xcb_connection()); + +@@ -1181,8 +1171,6 @@ void QXcbWindow::changeNetWmState(bool set, xcb_atom_t one, xcb_atom_t two) + event.data.data32[3] = 0; + event.data.data32[4] = 0; + +- if (!xcbScreen()) +- return; + Q_XCB_CALL(xcb_send_event(xcb_connection(), 0, xcbScreen()->root(), XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, (const char *)&event)); + } + +@@ -1435,8 +1423,6 @@ void QXcbWindow::setParent(const QPlatformWindow *parent) + xcb_parent_id = qXcbParent->xcb_window(); + m_embedded = qXcbParent->window()->type() == Qt::ForeignWindow; + } else { +- if (!xcbScreen()) +- return; + xcb_parent_id = xcbScreen()->root(); + m_embedded = false; + } +@@ -1992,7 +1978,7 @@ void QXcbWindow::handleConfigureNotifyEvent(const xcb_configure_notify_event_t * + { + bool fromSendEvent = (event->response_type & 0x80); + QPoint pos(event->x, event->y); +- if (!parent() && !fromSendEvent && xcbScreen()) { ++ if (!parent() && !fromSendEvent) { + // Do not trust the position, query it instead. + xcb_translate_coordinates_cookie_t cookie = xcb_translate_coordinates(xcb_connection(), xcb_window(), + xcbScreen()->root(), 0, 0); +@@ -2305,8 +2291,6 @@ void QXcbWindow::handleEnterNotifyEvent(const xcb_enter_notify_event_t *event) + return; + + const QPoint local(event->event_x, event->event_y); +- if (!xcbScreen()) +- return; + QPoint global = QPoint(event->root_x, event->root_y); + QWindowSystemInterface::handleEnterEvent(window(), local, global); + } +@@ -2324,8 +2308,6 @@ void QXcbWindow::handleLeaveNotifyEvent(const xcb_leave_notify_event_t *event) + + if (enterWindow) { + QPoint local(enter->event_x, enter->event_y); +- if (!xcbScreen()) +- return; + QPoint global = QPoint(event->root_x, event->root_y); + + QWindowSystemInterface::handleEnterLeaveEvent(enterWindow->window(), window(), local, global); +@@ -2341,8 +2323,6 @@ void QXcbWindow::handlePropertyNotifyEvent(const xcb_property_notify_event_t *ev + connection()->setTime(event->time); + + const bool propertyDeleted = event->state == XCB_PROPERTY_DELETE; +- if (!xcbScreen()) +- return; + + if (event->atom == atom(QXcbAtom::_NET_WM_STATE) || event->atom == atom(QXcbAtom::WM_STATE)) { + if (propertyDeleted) +@@ -2662,8 +2642,6 @@ bool QXcbWindow::needsSync() const + + void QXcbWindow::postSyncWindowRequest() + { +- if (!xcbScreen()) +- return; + if (!m_pendingSyncRequest) { + QXcbSyncWindowRequest *e = new QXcbSyncWindowRequest(this); + m_pendingSyncRequest = e; +diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h +index 0d14673..69c0819 100644 +--- a/src/plugins/platforms/xcb/qxcbwindow.h ++++ b/src/plugins/platforms/xcb/qxcbwindow.h +@@ -167,7 +167,6 @@ public: + + virtual void create(); + virtual void destroy(); +- void maybeSetScreen(QXcbScreen *screen); + QXcbScreen *screenForNativeGeometry(const QRect &newGeometry) const; + + public Q_SLOTS: +-- +2.5.0 + diff --git a/qt5-qtbase.spec b/qt5-qtbase.spec index 2a1bbe4..3215fd8 100644 --- a/qt5-qtbase.spec +++ b/qt5-qtbase.spec @@ -39,7 +39,7 @@ Summary: Qt5 - QtBase components Name: qt5-qtbase Version: 5.6.0 -Release: 0.7%{?dist} +Release: 0.8%{?dist} # See LGPL_EXCEPTIONS.txt, for exception details License: LGPLv2 with exceptions or GPLv3 with exceptions @@ -73,15 +73,16 @@ Patch50: qt5-poll.patch # https://bugzilla.redhat.com/show_bug.cgi?id=1083664 Patch51: qtbase-opensource-src-5.5-disconnect_displays.patch -# xcb: QScreen is a placeholder whenever there are no outputs connected -# https://codereview.qt-project.org/#/c/138201/ -Patch52: qtbase-opensource-src-5.6.0-xcb-gerrit-138201.patch - ## upstream patches # workaround https://bugreports.qt-project.org/browse/QTBUG-43057 # 'make docs' crash on el6, use qSort instead of std::sort Patch100: qtbase-opensource-src-5.4.0-QTBUG-43057.patch +Patch101: 0001-XCB-prevent-a-fp-division-by-zero.patch +Patch102: 0002-xcb-compare-to-previous-state-when-sending-geometry-.patch +Patch111: 0011-xcb-Don-t-cache-the-screen-for-a-window.patch +Patch112: 0012-xcb-Use-a-placeholder-QScreen-when-there-are-no-outp.patch + # macros, be mindful to keep sync'd with macros.qt5 Source10: macros.qt5 %define _qt5 %{name} @@ -321,12 +322,15 @@ rm -fv mkspecs/linux-g++*/qmake.conf.multilib-optflags %patch51 -p1 -b .disconnect_displays -%patch52 -p1 -b .138201 - %if 0%{?rhel} == 6 %patch100 -p1 -b .QTBUG-43057 %endif +%patch101 -p1 -b .0001 +%patch102 -p1 -b .0002 +%patch111 -p1 -b .0011 +%patch112 -p1 -b .0012 + # drop -fexceptions from $RPM_OPT_FLAGS RPM_OPT_FLAGS=`echo $RPM_OPT_FLAGS | sed 's|-fexceptions||g'` @@ -865,6 +869,9 @@ fi %changelog +* Fri Dec 11 2015 Rex Dieter 5.6.0-0.8 +- sync latest xcb/screen/display related upstream commits + * Thu Dec 10 2015 Helio Chissini de Castro - 5.6.0-0.7 - Official beta release From 72610001f04c179fc02ebd0957fb5fb017e7f803 Mon Sep 17 00:00:00 2001 From: Rex Dieter Date: Sat, 12 Dec 2015 18:17:38 -0600 Subject: [PATCH 3/3] drop disconnect_displays.patch so we can better test latest xcb/display work --- qt5-qtbase.spec | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/qt5-qtbase.spec b/qt5-qtbase.spec index 3215fd8..0cb60b1 100644 --- a/qt5-qtbase.spec +++ b/qt5-qtbase.spec @@ -39,7 +39,7 @@ Summary: Qt5 - QtBase components Name: qt5-qtbase Version: 5.6.0 -Release: 0.8%{?dist} +Release: 0.9%{?dist} # See LGPL_EXCEPTIONS.txt, for exception details License: LGPLv2 with exceptions or GPLv3 with exceptions @@ -320,7 +320,7 @@ rm -fv mkspecs/linux-g++*/qmake.conf.multilib-optflags %patch4 -p1 -b .QTBUG-35459 %patch12 -p1 -b .enable_ft_lcdfilter -%patch51 -p1 -b .disconnect_displays +#patch51 -p1 -b .disconnect_displays %if 0%{?rhel} == 6 %patch100 -p1 -b .QTBUG-43057 @@ -869,6 +869,9 @@ fi %changelog +* Sat Dec 12 2015 Rex Dieter 5.6.0-0.9 +- drop disconnect_displays.patch so we can better test latest xcb/display work + * Fri Dec 11 2015 Rex Dieter 5.6.0-0.8 - sync latest xcb/screen/display related upstream commits