diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h index 64e0068f0ef..b99a48cdc55 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.h +++ b/src/plugins/platforms/xcb/qxcbconnection.h @@ -226,9 +226,6 @@ private: void initializeScreensWithoutXRandR(xcb_screen_iterator_t *it, int screenNumber, QXcbScreen **primaryScreen); void initializeScreensFromOutput(xcb_screen_iterator_t *it, int screenNumber, QXcbScreen **primaryScreen); - void updateScreen_monitor(QXcbScreen *screen, xcb_randr_monitor_info_t *monitorInfo, xcb_timestamp_t timestamp = XCB_NONE); - QXcbScreen *createScreen_monitor(QXcbVirtualDesktop *virtualDesktop, - xcb_randr_monitor_info_t *monitorInfo, xcb_timestamp_t timestamp = XCB_NONE); QXcbVirtualDesktop* virtualDesktopForNumber(int n) const; QXcbScreen* findScreenForMonitorInfo(const QList &screens, xcb_randr_monitor_info_t *monitorInfo); void initializeScreensFromMonitor(xcb_screen_iterator_t *it, int screenNumber, QXcbScreen **primaryScreen, bool initialized); diff --git a/src/plugins/platforms/xcb/qxcbconnection_screens.cpp b/src/plugins/platforms/xcb/qxcbconnection_screens.cpp index cc1d9466d5e..a99538d6eb5 100644 --- a/src/plugins/platforms/xcb/qxcbconnection_screens.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection_screens.cpp @@ -246,40 +246,6 @@ void QXcbConnection::destroyScreen(QXcbScreen *screen) } } -void QXcbConnection::updateScreen_monitor(QXcbScreen *screen, xcb_randr_monitor_info_t *monitorInfo, xcb_timestamp_t timestamp) -{ - screen->setMonitor(monitorInfo, timestamp); - - if (screen->isPrimary()) { - const int idx = m_screens.indexOf(screen); - if (idx > 0) { - std::as_const(m_screens).first()->setPrimary(false); - m_screens.swapItemsAt(0, idx); - } - screen->virtualDesktop()->setPrimaryScreen(screen); - QWindowSystemInterface::handlePrimaryScreenChanged(screen); - } - qCDebug(lcQpaScreen) << "updateScreen_monitor: update" << screen << "(Primary:" << screen->isPrimary() << ")"; -} - -QXcbScreen *QXcbConnection::createScreen_monitor(QXcbVirtualDesktop *virtualDesktop, xcb_randr_monitor_info_t *monitorInfo, xcb_timestamp_t timestamp) -{ - QXcbScreen *screen = new QXcbScreen(this, virtualDesktop, monitorInfo, timestamp); - - if (screen->isPrimary()) { - if (!m_screens.isEmpty()) - std::as_const(m_screens).first()->setPrimary(false); - - m_screens.prepend(screen); - } else { - m_screens.append(screen); - } - qCDebug(lcQpaScreen) << "createScreen_monitor: adding" << screen << "(Primary:" << screen->isPrimary() << ")"; - virtualDesktop->addScreen(screen); - QWindowSystemInterface::handleScreenAdded(screen, screen->isPrimary()); - return screen; -} - QXcbVirtualDesktop *QXcbConnection::virtualDesktopForNumber(int n) const { for (QXcbVirtualDesktop *virtualDesktop : m_virtualDesktops) { @@ -489,7 +455,8 @@ void QXcbConnection::initializeScreensFromMonitor(xcb_screen_iterator_t *it, int virtualDesktop = new QXcbVirtualDesktop(this, xcbScreen, xcbScreenNumber); m_virtualDesktops.append(virtualDesktop); } - QList old = virtualDesktop->m_screens; + QList old = virtualDesktop->m_screens; + QList newScreens; QList siblings; @@ -510,25 +477,26 @@ void QXcbConnection::initializeScreensFromMonitor(xcb_screen_iterator_t *it, int } else { screen = findScreenForMonitorInfo(old, monitor_info); if (!screen) { - screen = createScreen_monitor(virtualDesktop, monitor_info, monitors_r->timestamp); + screen = new QXcbScreen(this, virtualDesktop, monitor_info, monitors_r->timestamp); + newScreens.append(screen); } else { - updateScreen_monitor(screen, monitor_info, monitors_r->timestamp); + screen->setMonitor(monitor_info, monitors_r->timestamp); old.removeAll(screen); } } - if (!m_screens.contains(screen)) - m_screens << screen; - siblings << screen; - // similar logic with QXcbConnection::initializeScreensFromOutput() - if (primaryScreenNumber() == xcbScreenNumber) { - if (!(*primaryScreen) || monitor_info->primary) { + if (screen->isPrimary()) { + siblings.prepend (screen); + if (primaryScreenNumber() == xcbScreenNumber) { if (*primaryScreen) (*primaryScreen)->setPrimary(false); *primaryScreen = screen; (*primaryScreen)->setPrimary(true); - siblings.prepend(siblings.takeLast()); + } else { // Only screens on the main virtual desktop can be primary + screen->setPrimary(false); } + } else { + siblings.append(screen); } xcb_randr_monitor_info_next(&monitor_iter); @@ -551,20 +519,47 @@ void QXcbConnection::initializeScreensFromMonitor(xcb_screen_iterator_t *it, int qCDebug(lcQpaScreen) << "create a fake screen: " << screen; } - if (primaryScreenNumber() == xcbScreenNumber) { - *primaryScreen = screen; + siblings << screen; + } + + if (primaryScreenNumber() == xcbScreenNumber) { + // If no screen was reported to be primary, use the first one + if (!*primaryScreen) { + (*primaryScreen) = static_cast(siblings.first()); (*primaryScreen)->setPrimary(true); } - siblings << screen; - m_screens << screen; + // Prepand the siblings to the current list of screens + QList new_m_screens; + new_m_screens.reserve( siblings.size() + m_screens.size() ); + for (QPlatformScreen *ps:siblings) { + new_m_screens.append(static_cast(ps)); + } + new_m_screens.append(std::move(m_screens)); + m_screens = std::move(new_m_screens); + } else { + for (QPlatformScreen *ps:siblings) { + m_screens.append(static_cast(ps)); + } } if (initialized) { + if (primaryScreenNumber() == xcbScreenNumber && !newScreens.contains(*primaryScreen)) { + qCDebug(lcQpaScreen) << "assigning screen as primary: " << *primaryScreen; + virtualDesktop->setPrimaryScreen(*primaryScreen); + QWindowSystemInterface::handlePrimaryScreenChanged(*primaryScreen); + } + + for (QXcbScreen *screen: newScreens) { + qCDebug(lcQpaScreen) << "adding screen: " << screen << "(Primary:" << screen->isPrimary() << ")"; + virtualDesktop->addScreen(screen); + QWindowSystemInterface::handleScreenAdded(screen, screen->isPrimary()); + } + for (QPlatformScreen *ps : old) { - virtualDesktop->removeScreen(ps); qCDebug(lcQpaScreen) << "destroy screen: " << ps; QWindowSystemInterface::handleScreenRemoved(ps); + virtualDesktop->removeScreen(ps); } }