Tooltips and Menus on wrong screen
-
Qt 6 app on Windows PC with 2 screens.
If the screens are identical, the result of QGuiApplication::screens().size() is 1. The geometry of this screen is the same as the second screen. Tooltips and popups/menus will appear on the wrong screen.
If the screens are different, the result of QGuiApplication::screens().size() is 2 and both have the correct geometry.
In the source code qwindowsscreen.cpp I found the following:static inline int indexOfMonitor(const WindowsScreenDataList &screenData, const QString &monitorName) { for (int i = 0; i < screenData.size(); ++i) if (screenData.at(i).name == monitorName) return i; return -1; } ///// bool QWindowsScreenManager::handleScreenChanges() { // Look for changed monitors, add new ones const WindowsScreenDataList newDataList = monitorData(); const bool lockScreen = newDataList.size() == 1 && (newDataList.front().flags & QWindowsScreenData::LockScreen); bool primaryScreenChanged = false; for (const QWindowsScreenData &newData : newDataList) { const int existingIndex = indexOfMonitor(m_screens, newData.name); if (existingIndex != -1) { m_screens.at(existingIndex)->handleChanges(newData); if (existingIndex == 0) primaryScreenChanged = true; } else { auto *newScreen = new QWindowsScreen(newData); m_screens.push_back(newScreen); QWindowSystemInterface::handleScreenAdded(newScreen, newData.flags & QWindowsScreenData::PrimaryScreen); qCDebug(lcQpaWindows) << "New Monitor: " << newData; } // exists } // for new screens. // Remove deleted ones but keep main monitors if we get only the // temporary lock screen to avoid window recreation (QTBUG-33062). if (!lockScreen) { for (int i = m_screens.size() - 1; i >= 0; --i) { if (indexOfMonitor(newDataList, m_screens.at(i)->data().name) == -1) removeScreen(i); } // for existing screens } // not lock screen if (primaryScreenChanged) { if (auto theme = QWindowsTheme::instance()) // QTBUG-85734/Wine theme->refreshFonts(); } return true; } //// void QWindowsScreen::handleChanges(const QWindowsScreenData &newData) { m_data.physicalSizeMM = newData.physicalSizeMM; if (m_data.hMonitor != newData.hMonitor) { qCDebug(lcQpaWindows) << "Monitor" << m_data.name << "has had its hMonitor handle changed from" << m_data.hMonitor << "to" << newData.hMonitor; m_data.hMonitor = newData.hMonitor; } // QGuiApplicationPrivate::processScreenGeometryChange() checks and emits // DPI and orientation as well, so, assign new values and emit DPI first. const bool geometryChanged = m_data.geometry != newData.geometry || m_data.availableGeometry != newData.availableGeometry; const bool dpiChanged = !qFuzzyCompare(m_data.dpi.first, newData.dpi.first) || !qFuzzyCompare(m_data.dpi.second, newData.dpi.second); const bool orientationChanged = m_data.orientation != newData.orientation; m_data.dpi = newData.dpi; m_data.orientation = newData.orientation; m_data.geometry = newData.geometry; m_data.availableGeometry = newData.availableGeometry; if (dpiChanged) { QWindowSystemInterface::handleScreenLogicalDotsPerInchChange(screen(), newData.dpi.first, newData.dpi.second); } if (orientationChanged) QWindowSystemInterface::handleScreenOrientationChange(screen(), newData.orientation); if (geometryChanged) { QWindowSystemInterface::handleScreenGeometryChange(screen(), newData.geometry, newData.availableGeometry); } }It seems like the first screen is overwritten with the data from the second screen. The indexOfMonitor method returns an incorrect index due to the screen name not being unique. How can this problem be solved?
-
I have been seeing this issue on MacOS as well. I cannot find a bug report for this. Are there any suggestions for a workaround?