summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/xcb/qxcbconnection.cpp
diff options
context:
space:
mode:
authorShawn Rutledge <shawn.rutledge@digia.com>2015-03-10 17:09:31 +0100
committerShawn Rutledge <shawn.rutledge@digia.com>2015-03-17 15:37:45 +0000
commitebdf9916600f0b0cd4d25b538d1fd0fef6e89077 (patch)
tree6d53c13b636e665a71ee2ed36ab4db1719a142ea /src/plugins/platforms/xcb/qxcbconnection.cpp
parentfcabeb2e4758b2d39cfc82928a22f8afdf27ba50 (diff)
xcb: create a screen if dimensions are known but outputs are not
This partially reverts 51ada7734ad780178ecced11e0dff454dfc2e5f2 because it's necessary to keep some scenarios with vnc and remote X servers working. When an application is starting, if we don't find the xrandr outputs but we know the dimensions of the screen, we should still be able to put windows onto that screen; but when we already had known xrandr outputs and then they were removed, that's the case where we want to stop rendering (and have no screen instances) until the screen(s) are reattached. Task-number: QTBUG-31389 Task-number: QTBUG-40174 Task-number: QTBUG-42985 Change-Id: I13d0996ba6ece78c4ebcd2c3a59f1617c1c7f0fa Reviewed-by: Uli Schlachter <psychon@znc.in> Reviewed-by: Gatis Paeglis <gatis.paeglis@digia.com> Reviewed-by: Laszlo Agocs <laszlo.agocs@theqtcompany.com>
Diffstat (limited to 'src/plugins/platforms/xcb/qxcbconnection.cpp')
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.cpp26
1 files changed, 21 insertions, 5 deletions
diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp
index d106473daa..3b3fcd0b49 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection.cpp
@@ -231,9 +231,8 @@ void QXcbConnection::updateScreens(const xcb_randr_notify_event_t *event)
QXcbIntegration::instance()->destroyScreen(screen);
- // QTBUG-40174, QTBUG-42985: If there are no outputs, then there must be
- // no QScreen instances; a Qt application can survive this situation, and
- // start rendering again later when there is a screen again.
+ // QTBUG-40174, QTBUG-42985: If all screens are removed, wait
+ // and start rendering again later if a screen becomes available.
} else if (!screen && output.connection == XCB_RANDR_CONNECTION_CONNECTED) {
// New XRandR output is available and it's enabled
@@ -293,13 +292,15 @@ 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 = NULL;
+ QXcbScreen* primaryScreen = Q_NULLPTR;
+ xcb_screen_t *xcbScreen = Q_NULLPTR;
+ bool hasOutputs = false;
while (it.rem) {
// Each "screen" in xcb terminology is a virtual desktop,
// potentially a collection of separate juxtaposed monitors.
// But we want a separate QScreen for each output (e.g. DVI-I-1, VGA-1, etc.)
// which will become virtual siblings.
- xcb_screen_t *xcbScreen = it.data;
+ xcbScreen = it.data;
QList<QPlatformScreen *> siblings;
int outputCount = 0;
int connectedOutputCount = 0;
@@ -356,6 +357,7 @@ void QXcbConnection::initializeScreens()
QXcbScreen *screen = createScreen(xcbScreenNumber, xcbScreen, outputs[i], output.data());
siblings << screen;
++connectedOutputCount;
+ hasOutputs = true;
m_screens << screen;
// There can be multiple outputs per screen, use either
@@ -381,6 +383,20 @@ 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)
+ if (xcbScreen && !hasOutputs && xcbScreen->width_in_pixels > 0 && xcbScreen->height_in_pixels > 0 && m_screens.isEmpty()) {
+ QXcbScreen *screen = createScreen(0, xcbScreen, 0, Q_NULLPTR);
+ screen->setVirtualSiblings(QList<QPlatformScreen *>() << 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());