87 lines
4.3 KiB
Diff
87 lines
4.3 KiB
Diff
commit ebdf9916600f0b0cd4d25b538d1fd0fef6e89077
|
|
Author: Shawn Rutledge <shawn.rutledge@digia.com>
|
|
Date: Tue Mar 10 17:09:31 2015 +0100
|
|
|
|
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>
|
|
|
|
diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp
|
|
index 523ae79..89a0083 100644
|
|
--- a/src/plugins/platforms/xcb/qxcbconnection.cpp
|
|
+++ b/src/plugins/platforms/xcb/qxcbconnection.cpp
|
|
@@ -270,9 +270,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
|
|
@@ -332,13 +331,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;
|
|
@@ -395,6 +396,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
|
|
@@ -420,6 +422,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());
|