xcb: only set primary for monitor on primary X screen
It's possible to have multiple X screens, and a primary monitor on each X screen. We should only use one on primary X screen as primary QScreen. The reference of QXcbScreen pointer should be used correctly. Fixes: QTBUG-102758 Pick-to: 6.3 Change-Id: I1eafd509c8c109606967a4abe9ad7e9d8c0dd464 Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
This commit is contained in:
parent
bd1023a824
commit
731b38e768
@ -226,14 +226,14 @@ private:
|
|||||||
xcb_randr_get_output_info_reply_t *outputInfo);
|
xcb_randr_get_output_info_reply_t *outputInfo);
|
||||||
void destroyScreen(QXcbScreen *screen);
|
void destroyScreen(QXcbScreen *screen);
|
||||||
void initializeScreens(bool initialized);
|
void initializeScreens(bool initialized);
|
||||||
void initializeScreensFromOutput(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);
|
void updateScreen_monitor(QXcbScreen *screen, xcb_randr_monitor_info_t *monitorInfo, xcb_timestamp_t timestamp = XCB_NONE);
|
||||||
QXcbScreen *createScreen_monitor(QXcbVirtualDesktop *virtualDesktop,
|
QXcbScreen *createScreen_monitor(QXcbVirtualDesktop *virtualDesktop,
|
||||||
xcb_randr_monitor_info_t *monitorInfo, xcb_timestamp_t timestamp = XCB_NONE);
|
xcb_randr_monitor_info_t *monitorInfo, xcb_timestamp_t timestamp = XCB_NONE);
|
||||||
QXcbVirtualDesktop* virtualDesktopForNumber(int n) const;
|
QXcbVirtualDesktop* virtualDesktopForNumber(int n) const;
|
||||||
QXcbScreen* findScreenForMonitorInfo(const QList<QPlatformScreen *> &screens, xcb_randr_monitor_info_t *monitorInfo);
|
QXcbScreen* findScreenForMonitorInfo(const QList<QPlatformScreen *> &screens, xcb_randr_monitor_info_t *monitorInfo);
|
||||||
void initializeScreensFromMonitor(xcb_screen_iterator_t *it, int screenNumber, QXcbScreen *primaryScreen, bool initialized);
|
void initializeScreensFromMonitor(xcb_screen_iterator_t *it, int screenNumber, QXcbScreen **primaryScreen, bool initialized);
|
||||||
|
|
||||||
bool compressEvent(xcb_generic_event_t *event) const;
|
bool compressEvent(xcb_generic_event_t *event) const;
|
||||||
inline bool timeGreaterThan(xcb_timestamp_t a, xcb_timestamp_t b) const
|
inline bool timeGreaterThan(xcb_timestamp_t a, xcb_timestamp_t b) const
|
||||||
|
@ -309,11 +309,14 @@ void QXcbConnection::initializeScreens(bool initialized)
|
|||||||
xcb_screen_iterator_t it = xcb_setup_roots_iterator(setup());
|
xcb_screen_iterator_t it = xcb_setup_roots_iterator(setup());
|
||||||
int xcbScreenNumber = 0; // screen number in the xcb sense
|
int xcbScreenNumber = 0; // screen number in the xcb sense
|
||||||
QXcbScreen *primaryScreen = nullptr;
|
QXcbScreen *primaryScreen = nullptr;
|
||||||
|
if (isAtLeastXRandR15() && initialized)
|
||||||
|
m_screens.clear();
|
||||||
|
|
||||||
while (it.rem) {
|
while (it.rem) {
|
||||||
if (isAtLeastXRandR15())
|
if (isAtLeastXRandR15())
|
||||||
initializeScreensFromMonitor(&it, xcbScreenNumber, primaryScreen, initialized);
|
initializeScreensFromMonitor(&it, xcbScreenNumber, &primaryScreen, initialized);
|
||||||
else if (isAtLeastXRandR12())
|
else if (isAtLeastXRandR12())
|
||||||
initializeScreensFromOutput(&it, xcbScreenNumber, primaryScreen);
|
initializeScreensFromOutput(&it, xcbScreenNumber, &primaryScreen);
|
||||||
|
|
||||||
xcb_screen_next(&it);
|
xcb_screen_next(&it);
|
||||||
++xcbScreenNumber;
|
++xcbScreenNumber;
|
||||||
@ -346,7 +349,7 @@ void QXcbConnection::initializeScreens(bool initialized)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void QXcbConnection::initializeScreensFromOutput(xcb_screen_iterator_t *it, int xcbScreenNumber, QXcbScreen *primaryScreen)
|
void QXcbConnection::initializeScreensFromOutput(xcb_screen_iterator_t *it, int xcbScreenNumber, QXcbScreen **primaryScreen)
|
||||||
{
|
{
|
||||||
// Each "screen" in xcb terminology is a virtual desktop,
|
// Each "screen" in xcb terminology is a virtual desktop,
|
||||||
// potentially a collection of separate juxtaposed monitors.
|
// potentially a collection of separate juxtaposed monitors.
|
||||||
@ -420,11 +423,11 @@ void QXcbConnection::initializeScreensFromOutput(xcb_screen_iterator_t *it, int
|
|||||||
// always available if primary->output is XCB_NONE
|
// always available if primary->output is XCB_NONE
|
||||||
// or currently disconnected output.
|
// or currently disconnected output.
|
||||||
if (primaryScreenNumber() == xcbScreenNumber) {
|
if (primaryScreenNumber() == xcbScreenNumber) {
|
||||||
if (!primaryScreen || (primary && outputs[i] == primary->output)) {
|
if (!(*primaryScreen) || (primary && outputs[i] == primary->output)) {
|
||||||
if (primaryScreen)
|
if (*primaryScreen)
|
||||||
primaryScreen->setPrimary(false);
|
(*primaryScreen)->setPrimary(false);
|
||||||
primaryScreen = screen;
|
*primaryScreen = screen;
|
||||||
primaryScreen->setPrimary(true);
|
(*primaryScreen)->setPrimary(true);
|
||||||
siblings.prepend(siblings.takeLast());
|
siblings.prepend(siblings.takeLast());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -440,15 +443,15 @@ void QXcbConnection::initializeScreensFromOutput(xcb_screen_iterator_t *it, int
|
|||||||
qCDebug(lcQpaScreen) << "created fake screen" << screen;
|
qCDebug(lcQpaScreen) << "created fake screen" << screen;
|
||||||
m_screens << screen;
|
m_screens << screen;
|
||||||
if (primaryScreenNumber() == xcbScreenNumber) {
|
if (primaryScreenNumber() == xcbScreenNumber) {
|
||||||
primaryScreen = screen;
|
*primaryScreen = screen;
|
||||||
primaryScreen->setPrimary(true);
|
(*primaryScreen)->setPrimary(true);
|
||||||
}
|
}
|
||||||
siblings << screen;
|
siblings << screen;
|
||||||
}
|
}
|
||||||
virtualDesktop->setScreens(std::move(siblings));
|
virtualDesktop->setScreens(std::move(siblings));
|
||||||
}
|
}
|
||||||
|
|
||||||
void QXcbConnection::initializeScreensFromMonitor(xcb_screen_iterator_t *it, int xcbScreenNumber, QXcbScreen *primaryScreen, bool initialized)
|
void QXcbConnection::initializeScreensFromMonitor(xcb_screen_iterator_t *it, int xcbScreenNumber, QXcbScreen **primaryScreen, bool initialized)
|
||||||
{
|
{
|
||||||
// Each "screen" in xcb terminology is a virtual desktop,
|
// Each "screen" in xcb terminology is a virtual desktop,
|
||||||
// potentially a collection of separate juxtaposed monitors.
|
// potentially a collection of separate juxtaposed monitors.
|
||||||
@ -463,8 +466,6 @@ void QXcbConnection::initializeScreensFromMonitor(xcb_screen_iterator_t *it, int
|
|||||||
m_virtualDesktops.append(virtualDesktop);
|
m_virtualDesktops.append(virtualDesktop);
|
||||||
}
|
}
|
||||||
QList<QPlatformScreen*> old = virtualDesktop->m_screens;
|
QList<QPlatformScreen*> old = virtualDesktop->m_screens;
|
||||||
if (initialized)
|
|
||||||
m_screens.clear();
|
|
||||||
|
|
||||||
QList<QPlatformScreen *> siblings;
|
QList<QPlatformScreen *> siblings;
|
||||||
|
|
||||||
@ -482,21 +483,30 @@ void QXcbConnection::initializeScreensFromMonitor(xcb_screen_iterator_t *it, int
|
|||||||
QXcbScreen *screen = nullptr;
|
QXcbScreen *screen = nullptr;
|
||||||
if (!initialized) {
|
if (!initialized) {
|
||||||
screen = new QXcbScreen(this, virtualDesktop, monitor_info, monitors_r->timestamp);
|
screen = new QXcbScreen(this, virtualDesktop, monitor_info, monitors_r->timestamp);
|
||||||
m_screens << screen;
|
|
||||||
} else {
|
} else {
|
||||||
screen = findScreenForMonitorInfo(virtualDesktop->m_screens, monitor_info);
|
screen = findScreenForMonitorInfo(old, monitor_info);
|
||||||
if (!screen) {
|
if (!screen) {
|
||||||
screen = createScreen_monitor(virtualDesktop, monitor_info, monitors_r->timestamp);
|
screen = createScreen_monitor(virtualDesktop, monitor_info, monitors_r->timestamp);
|
||||||
QHighDpiScaling::updateHighDpiScaling();
|
QHighDpiScaling::updateHighDpiScaling();
|
||||||
} else {
|
} else {
|
||||||
m_screens << screen;
|
|
||||||
updateScreen_monitor(screen, monitor_info, monitors_r->timestamp);
|
updateScreen_monitor(screen, monitor_info, monitors_r->timestamp);
|
||||||
old.removeAll(screen);
|
old.removeAll(screen);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
m_screens << screen;
|
||||||
siblings << screen;
|
siblings << screen;
|
||||||
|
|
||||||
|
// similar logic with QXcbConnection::initializeScreensFromOutput()
|
||||||
|
if (primaryScreenNumber() == xcbScreenNumber) {
|
||||||
|
if (!(*primaryScreen) || monitor_info->primary) {
|
||||||
|
if (*primaryScreen)
|
||||||
|
(*primaryScreen)->setPrimary(false);
|
||||||
|
*primaryScreen = screen;
|
||||||
|
(*primaryScreen)->setPrimary(true);
|
||||||
|
siblings.prepend(siblings.takeLast());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
xcb_randr_monitor_info_next(&monitor_iter);
|
xcb_randr_monitor_info_next(&monitor_iter);
|
||||||
}
|
}
|
||||||
free(monitors_r);
|
free(monitors_r);
|
||||||
@ -518,9 +528,10 @@ void QXcbConnection::initializeScreensFromMonitor(xcb_screen_iterator_t *it, int
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (primaryScreenNumber() == xcbScreenNumber) {
|
if (primaryScreenNumber() == xcbScreenNumber) {
|
||||||
primaryScreen = screen;
|
*primaryScreen = screen;
|
||||||
primaryScreen->setPrimary(true);
|
(*primaryScreen)->setPrimary(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
siblings << screen;
|
siblings << screen;
|
||||||
m_screens << screen;
|
m_screens << screen;
|
||||||
}
|
}
|
||||||
|
@ -678,7 +678,10 @@ void QXcbScreen::setMonitor(xcb_randr_monitor_info_t *monitorInfo, xcb_timestamp
|
|||||||
m_sizeMillimeters = virtualDesktop()->physicalSize();
|
m_sizeMillimeters = virtualDesktop()->physicalSize();
|
||||||
|
|
||||||
m_outputName = getName(monitorInfo);
|
m_outputName = getName(monitorInfo);
|
||||||
m_primary = monitorInfo->primary;
|
if (connection()->primaryScreenNumber() == virtualDesktop()->number() && monitorInfo->primary)
|
||||||
|
m_primary = true;
|
||||||
|
else
|
||||||
|
m_primary = false;
|
||||||
|
|
||||||
m_cursor = new QXcbCursor(connection(), this);
|
m_cursor = new QXcbCursor(connection(), this);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user