- Uploading 5.6. beta 2

This commit is contained in:
Helio Chissini de Castro 2015-12-05 20:47:59 +01:00
parent c6a7f1a513
commit 341f22d360
4 changed files with 742 additions and 18 deletions

1
.gitignore vendored
View File

@ -1 +1,2 @@
/qtbase-opensource-src-5.5.1.tar.xz
/qtbase-opensource-src-5.6.0-beta2.tar.xz

View File

@ -22,14 +22,12 @@
%define docs 1
%define examples 1
%define prerelease beta1
%define prerelease beta2
Summary: Qt5 - QtBase components
Name: qt5-qtbase
Version: 5.6.0
Release: 0.2%{?dist}
Release: 0.3%{?dist}
# See LGPL_EXCEPTIONS.txt, for exception details
License: LGPLv2 with exceptions or GPLv3 with exceptions
@ -63,6 +61,10 @@ Patch50: qt5-poll.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=1083664
Patch51: qtbase-opensource-src-5.5-disconnect_displays.patch
# xcb: QScreen is a placeholder whenever there are no outputs connected
# https://codereview.qt-project.org/#/c/138201/
Patch52: qtbase-opensource-src-5.6.0-xcb-gerrit-138201.patch
## upstream patches
# workaround https://bugreports.qt-project.org/browse/QTBUG-43057
# 'make docs' crash on el6, use qSort instead of std::sort
@ -203,6 +205,11 @@ Requires: %{name}-gui%{?_isa}
Requires: pkgconfig(egl)
%endif
Requires: pkgconfig(gl)
%if 0%{?fedora} > 22
# https://bugzilla.redhat.com/show_bug.cgi?id=1248174
Requires: redhat-rpm-config
%endif
%description devel
%{summary}.
@ -300,21 +307,16 @@ rm -fv mkspecs/linux-g++*/qmake.conf.multilib-optflags
%patch4 -p1 -b .QTBUG-35459
%patch12 -p1 -b .enable_ft_lcdfilter
#patch50 -p1 -b .poll
%patch51 -p1 -b .disconnect_displays
%patch52 -p1 -b .138201
%if 0%{?rhel} == 6
%patch100 -p1 -b .QTBUG-43057
%endif
# drop -fexceptions from $RPM_OPT_FLAGS
RPM_OPT_FLAGS=`echo $RPM_OPT_FLAGS | sed 's|-fexceptions||g'`
%ifarch %{ix86}
%if 0%{?fedora} > 22
RPM_OPT_FLAGS=`echo $RPM_OPT_FLAGS | sed 's|-fasynchronous-unwind-tables||g'`
RPM_OPT_FLAGS=`echo $RPM_OPT_FLAGS | sed 's|--param=ssp-buffer-size=4||g'`
%endif
%endif
%define platform linux-g++
@ -354,10 +356,7 @@ test -x configure || chmod +x configure
-bindir %{_qt5_bindir} \
-datadir %{_qt5_datadir} \
-docdir %{_qt5_docdir} \
%if 0%{?examples}
-examplesdir %{_qt5_examplesdir} \
-no-compile-examples \
%endif
-headerdir %{_qt5_headerdir} \
-importdir %{_qt5_importdir} \
-libdir %{_qt5_libdir} \
@ -750,10 +749,8 @@ fi
%{_qt5_libdir}/libQt5PlatformSupport.*a
%{_qt5_libdir}/libQt5PlatformSupport.prl
%if 0%{?examples}
%files examples
%{_qt5_examplesdir}/
%endif
%if "%{?ibase}" != "-no-sql-ibase"
%files ibase
@ -845,18 +842,40 @@ fi
%changelog
* Fri Nov 13 2015 Helio Chissini de Castro <helio@kde.org> - 5.6.0-0.2
* Sat Dec 05 2015 Helio Chissini de Castro <helio@kde.org> - 5.6.0-0.3
- Beta 3
- Reintroduce xcb patch from https://codereview.qt-project.org/#/c/138201/
* Fri Nov 27 2015 Helio Chissini de Castro <helio@kde.org> - 5.6.0-0.2
- Valgrind still needed as buildreq due recent split qdoc package, but we can get rid of
specific arch set.
- Added missing libproxy buildreq
- Epel and RHEL doesn't have libinput, so a plugin need to be excluded for this distros
* Wed Nov 25 2015 Rex Dieter <rdieter@fedoraproject.org> 5.5.1-10
- -devel: Requires: redhat-rpm-config (#1248174)
* Wed Nov 18 2015 Helio Chissini de Castro <helio@kde.org> - 5.5.1-9
- Get rid of valgrind hack. It sort out that we don't need it anymore (#1211203)
* Mon Nov 09 2015 Helio Chissini de Castro <helio@kde.org> - 5.5.1-8
- qt5-qdoc need requires >= current version, otherwise will prevent the usage further when moved to qttools
* Mon Nov 09 2015 Rex Dieter <rdieter@fedoraproject.org> 5.5.1-7
- qt5-qdoc subpkg
* Tue Nov 03 2015 Helio Chissini de Castro <helio@kde.org> - 5.6.0-0.1
- Start to implement 5.6.0 beta
* Tue Nov 03 2015 Helio Chissini de Castro <helio@kde.org> - 5.6.0-0.1
- Start to implement 5.6.0 beta
* Wed Oct 28 2015 David Tardon <dtardon@redhat.com> - 5.5.1-6
- full build
* Wed Oct 28 2015 David Tardon <dtardon@redhat.com> - 5.5.1-5
- rebuild for ICU 56.1
* Thu Oct 15 2015 Helio Chissini de Castro <helio@kde.org> - 5.5.1-2
- Update to final release 5.5.1

View File

@ -0,0 +1,704 @@
From 56657b57083caa77e368452b07224bb70082bbc6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?B=C5=82a=C5=BCej=20Szczygie=C5=82?= <spaz16@wp.pl>
Date: Fri, 16 Oct 2015 22:51:59 +0200
Subject: [PATCH] xcb: QScreen is a placeholder whenever there are no outputs
connected
If no screens are available, windows could disappear, could stop rendering
graphics, or the application could crash. This is a real use case in several
scenarios: with x11vnc, when all monitors are physically disconnected from a
desktop machine, or in some cases even when the monitor sleeps. Now when the
last screen is disconnected, it is transformed into a fake screen. When a
physical screen appears, the fake QScreen is transformed into a representation
of the physical screen. Every virtual desktop has its own fake screen, and
primary screens must belong to the primary virtual desktop. It fixes updating
screen geometry on temporarily disabled screens in the middle of the mode
switch.
Expected results: Windows don't disappear, the application doesn't
crash, and QMenu is displayed on the appropriate screen.
This reverts patch 51ada7734ad780178ecced11e0dff454dfc2e5f2
Change-Id: I6e8eb682b0c8425d08ffdaecbd4c6c7700c914b4
Task-number: QTBUG-42985
---
src/gui/kernel/qscreen.cpp | 4 +-
src/plugins/platforms/xcb/qxcbconnection.cpp | 265 +++++++++++++++------------
src/plugins/platforms/xcb/qxcbconnection.h | 10 +-
src/plugins/platforms/xcb/qxcbscreen.cpp | 49 +++--
src/plugins/platforms/xcb/qxcbscreen.h | 10 +-
src/plugins/platforms/xcb/qxcbwindow.cpp | 38 +---
src/plugins/platforms/xcb/qxcbwindow.h | 1 -
7 files changed, 205 insertions(+), 172 deletions(-)
diff --git a/src/gui/kernel/qscreen.cpp b/src/gui/kernel/qscreen.cpp
index b6b5037..4338db2 100644
--- a/src/gui/kernel/qscreen.cpp
+++ b/src/gui/kernel/qscreen.cpp
@@ -116,8 +116,8 @@ QScreen::~QScreen()
bool movingFromVirtualSibling = primaryScreen && primaryScreen->handle()->virtualSiblings().contains(handle());
// Move any leftover windows to the primary screen
- foreach (QWindow *window, QGuiApplication::topLevelWindows()) {
- if (window->screen() != this)
+ foreach (QWindow *window, QGuiApplication::allWindows()) {
+ if (!window->isTopLevel() || window->screen() != this)
continue;
const bool wasVisible = window->isVisible();
diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp
index 901764b..66a794a 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection.cpp
@@ -179,42 +179,6 @@ QXcbScreen* QXcbConnection::findScreenForOutput(xcb_window_t rootWindow, xcb_ran
return 0;
}
-QXcbScreen* QXcbConnection::createScreen(QXcbVirtualDesktop* virtualDesktop,
- xcb_randr_output_t outputId,
- xcb_randr_get_output_info_reply_t *output)
-{
- QString name;
- if (output)
- name = QString::fromUtf8((const char*)xcb_randr_get_output_info_name(output),
- xcb_randr_get_output_info_name_length(output));
- else {
- QByteArray displayName = m_displayName;
- int dotPos = displayName.lastIndexOf('.');
- if (dotPos != -1)
- displayName.truncate(dotPos);
- name = QString::fromLocal8Bit(displayName) + QLatin1Char('.') + QString::number(virtualDesktop->number());
- }
-
- return new QXcbScreen(this, virtualDesktop, outputId, output, name);
-}
-
-bool QXcbConnection::checkOutputIsPrimary(xcb_window_t rootWindow, xcb_randr_output_t output)
-{
- xcb_generic_error_t *error = 0;
- xcb_randr_get_output_primary_cookie_t primaryCookie =
- xcb_randr_get_output_primary(xcb_connection(), rootWindow);
- QScopedPointer<xcb_randr_get_output_primary_reply_t, QScopedPointerPodDeleter> primary (
- xcb_randr_get_output_primary_reply(xcb_connection(), primaryCookie, &error));
- if (!primary || error) {
- qWarning("failed to get the primary output of the screen");
- free(error);
- error = NULL;
- }
- const bool isPrimary = primary ? (primary->output == output) : false;
-
- return isPrimary;
-}
-
QXcbVirtualDesktop* QXcbConnection::virtualDesktopForRootWindow(xcb_window_t rootWindow)
{
foreach (QXcbVirtualDesktop *virtualDesktop, m_virtualDesktops) {
@@ -260,16 +224,7 @@ void QXcbConnection::updateScreens(const xcb_randr_notify_event_t *event)
if (screen && output.connection == XCB_RANDR_CONNECTION_DISCONNECTED) {
qCDebug(lcQpaScreen) << "screen" << screen->name() << "has been disconnected";
-
- // Known screen removed -> delete it
- m_screens.removeOne(screen);
- virtualDesktop->removeScreen(screen);
-
- QXcbIntegration::instance()->destroyScreen(screen);
-
- // QTBUG-40174, QTBUG-42985: If all screens are removed, wait
- // and start rendering again later if a screen becomes available.
-
+ destroyScreen(screen);
} else if (!screen && output.connection == XCB_RANDR_CONNECTION_CONNECTED) {
// New XRandR output is available and it's enabled
if (output.crtc != XCB_NONE && output.mode != XCB_NONE) {
@@ -278,59 +233,138 @@ void QXcbConnection::updateScreens(const xcb_randr_notify_event_t *event)
QScopedPointer<xcb_randr_get_output_info_reply_t, QScopedPointerPodDeleter> outputInfo(
xcb_randr_get_output_info_reply(xcb_connection(), outputInfoCookie, NULL));
- screen = createScreen(virtualDesktop, output.output, outputInfo.data());
- qCDebug(lcQpaScreen) << "output" << screen->name() << "is connected and enabled";
+ // Find a fake screen
+ foreach (QPlatformScreen *screen, virtualDesktop->screens()) {
+ QXcbScreen *xcbScreen = (QXcbScreen *)screen;
+ if (xcbScreen->output() == XCB_NONE) {
+ screen = xcbScreen;
+ break;
+ }
+ }
- screen->setPrimary(checkOutputIsPrimary(output.window, output.output));
- virtualDesktop->addScreen(screen);
- m_screens << screen;
- QXcbIntegration::instance()->screenAdded(screen, screen->isPrimary());
-
- // Windows which had null screens have already had expose events by now.
- // They need to be told the screen is back, it's OK to render.
- foreach (QWindow *window, QGuiApplication::topLevelWindows()) {
- QXcbWindow *xcbWin = static_cast<QXcbWindow*>(window->handle());
- if (xcbWin)
- xcbWin->maybeSetScreen(screen);
+ if (screen) {
+ // Transform the fake screen into a physical screen
+ screen->setOutput(output.output, outputInfo.data());
+ updateScreen(screen, output);
+ } else {
+ screen = createScreen(virtualDesktop, output, outputInfo.data());
}
+
+ qCDebug(lcQpaScreen) << "output" << screen->name() << "is connected and enabled";
}
- // else ignore disabled screens
} else if (screen) {
- // Screen has been disabled -> remove
if (output.crtc == XCB_NONE && output.mode == XCB_NONE) {
+ // Screen has been disabled
xcb_randr_get_output_info_cookie_t outputInfoCookie =
xcb_randr_get_output_info(xcb_connection(), output.output, output.config_timestamp);
QScopedPointer<xcb_randr_get_output_info_reply_t, QScopedPointerPodDeleter> outputInfo(
xcb_randr_get_output_info_reply(xcb_connection(), outputInfoCookie, NULL));
if (outputInfo->crtc == XCB_NONE) {
qCDebug(lcQpaScreen) << "output" << screen->name() << "has been disabled";
- m_screens.removeOne(screen);
- virtualDesktop->removeScreen(screen);
- QXcbIntegration::instance()->destroyScreen(screen);
+ destroyScreen(screen);
} else {
qCDebug(lcQpaScreen) << "output" << screen->name() << "has been temporarily disabled for the mode switch";
+ // Reset crtc to skip RRCrtcChangeNotify events,
+ // because they may be invalid in the middle of the mode switch
+ screen->setCrtc(XCB_NONE);
}
} else {
- // Just update existing screen
- screen->updateGeometry(output.config_timestamp);
- const bool wasPrimary = screen->isPrimary();
- screen->setPrimary(checkOutputIsPrimary(output.window, output.output));
- if (screen->mode() != output.mode)
- screen->updateRefreshRate(output.mode);
-
- // If the screen became primary, reshuffle the order in QGuiApplicationPrivate
- if (!wasPrimary && screen->isPrimary()) {
- const int idx = m_screens.indexOf(screen);
- m_screens.swap(0, idx);
- QXcbIntegration::instance()->setPrimaryScreen(screen);
- }
+ updateScreen(screen, output);
qCDebug(lcQpaScreen) << "output has changed" << screen;
}
}
+
+ qCDebug(lcQpaScreen) << "primary output is" << m_screens.first()->name();
+ }
+}
+
+bool QXcbConnection::checkOutputIsPrimary(xcb_window_t rootWindow, xcb_randr_output_t output)
+{
+ xcb_generic_error_t *error = 0;
+ xcb_randr_get_output_primary_cookie_t primaryCookie =
+ xcb_randr_get_output_primary(xcb_connection(), rootWindow);
+ QScopedPointer<xcb_randr_get_output_primary_reply_t, QScopedPointerPodDeleter> primary (
+ xcb_randr_get_output_primary_reply(xcb_connection(), primaryCookie, &error));
+ if (!primary || error) {
+ qWarning("failed to get the primary output of the screen");
+ free(error);
+ error = NULL;
+ }
+ const bool isPrimary = primary ? (primary->output == output) : false;
+
+ return isPrimary;
+}
+
+void QXcbConnection::updateScreen(QXcbScreen *screen, const xcb_randr_output_change_t &outputChange)
+{
+ screen->setCrtc(outputChange.crtc); // Set the new crtc, because it can be invalid
+ screen->updateGeometry(outputChange.config_timestamp);
+ if (screen->mode() != outputChange.mode)
+ screen->updateRefreshRate(outputChange.mode);
+ // Only screen which belongs to the primary virtual desktop can be a primary screen
+ if (screen->screenNumber() == m_primaryScreenNumber) {
+ if (!screen->isPrimary() && checkOutputIsPrimary(outputChange.window, outputChange.output)) {
+ screen->setPrimary(true);
+
+ // If the screen became primary, reshuffle the order in QGuiApplicationPrivate
+ const int idx = m_screens.indexOf(screen);
+ if (idx > 0) {
+ m_screens.first()->setPrimary(false);
+ m_screens.swap(0, idx);
+ }
+ screen->virtualDesktop()->setPrimaryScreen(screen);
+ QXcbIntegration::instance()->setPrimaryScreen(screen);
+ }
+ }
+}
+
+QXcbScreen *QXcbConnection::createScreen(QXcbVirtualDesktop *virtualDesktop,
+ const xcb_randr_output_change_t &outputChange,
+ xcb_randr_get_output_info_reply_t *outputInfo)
+{
+ QXcbScreen *screen = new QXcbScreen(this, virtualDesktop, outputChange.output, outputInfo);
+ // Only screen which belongs to the primary virtual desktop can be a primary screen
+ if (screen->screenNumber() == m_primaryScreenNumber)
+ screen->setPrimary(checkOutputIsPrimary(outputChange.window, outputChange.output));
+
+ if (screen->isPrimary()) {
if (!m_screens.isEmpty())
- qCDebug(lcQpaScreen) << "primary output is" << m_screens.first()->name();
- else
- qCDebug(lcQpaScreen) << "no outputs";
+ m_screens.first()->setPrimary(false);
+
+ m_screens.prepend(screen);
+ } else {
+ m_screens.append(screen);
+ }
+ virtualDesktop->addScreen(screen);
+ QXcbIntegration::instance()->screenAdded(screen, screen->isPrimary());
+
+ return screen;
+}
+
+void QXcbConnection::destroyScreen(QXcbScreen *screen)
+{
+ QXcbVirtualDesktop *virtualDesktop = screen->virtualDesktop();
+ if (virtualDesktop->screens().count() == 1) {
+ // If there are no other screens on the same virtual desktop,
+ // then transform the physical screen into a fake screen.
+ screen->setOutput(XCB_NONE, Q_NULLPTR);
+ } else {
+ // There is more than one screen on the same virtual desktop, remove the screen
+ m_screens.removeOne(screen);
+ virtualDesktop->removeScreen(screen);
+
+ // When primary screen is removed, set the new primary screen
+ // which belongs to the primary virtual desktop.
+ if (screen->isPrimary()) {
+ QXcbScreen *newPrimary = (QXcbScreen *)virtualDesktop->screens().at(0);
+ newPrimary->setPrimary(true);
+ const int idx = m_screens.indexOf(newPrimary);
+ if (idx > 0)
+ m_screens.swap(0, idx);
+ QXcbIntegration::instance()->setPrimaryScreen(newPrimary);
+ }
+
+ QXcbIntegration::instance()->destroyScreen(screen);
}
}
@@ -338,8 +372,7 @@ 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 = Q_NULLPTR;
- bool hasOutputs = false;
+ QXcbScreen *primaryScreen = Q_NULLPTR;
while (it.rem) {
// Each "screen" in xcb terminology is a virtual desktop,
// potentially a collection of separate juxtaposed monitors.
@@ -348,8 +381,6 @@ void QXcbConnection::initializeScreens()
xcb_screen_t *xcbScreen = it.data;
QXcbVirtualDesktop *virtualDesktop = new QXcbVirtualDesktop(this, xcbScreen, xcbScreenNumber);
m_virtualDesktops.append(virtualDesktop);
- QList<QPlatformScreen *> siblings;
- int outputCount = 0;
if (has_randr_extension) {
xcb_generic_error_t *error = NULL;
// RRGetScreenResourcesCurrent is fast but it may return nothing if the
@@ -366,7 +397,7 @@ void QXcbConnection::initializeScreens()
} else {
xcb_timestamp_t timestamp;
xcb_randr_output_t *outputs = Q_NULLPTR;
- outputCount = xcb_randr_get_screen_resources_current_outputs_length(resources_current.data());
+ int outputCount = xcb_randr_get_screen_resources_current_outputs_length(resources_current.data());
if (outputCount) {
timestamp = resources_current->config_timestamp;
outputs = xcb_randr_get_screen_resources_current_outputs(resources_current.data());
@@ -393,6 +424,7 @@ void QXcbConnection::initializeScreens()
qWarning("failed to get the primary output of the screen");
free(error);
} else {
+ QList<QPlatformScreen *> siblings;
for (int i = 0; i < outputCount; i++) {
QScopedPointer<xcb_randr_get_output_info_reply_t, QScopedPointerPodDeleter> output(
xcb_randr_get_output_info_reply(xcb_connection(),
@@ -416,9 +448,8 @@ void QXcbConnection::initializeScreens()
continue;
}
- QXcbScreen *screen = createScreen(virtualDesktop, outputs[i], output.data());
+ QXcbScreen *screen = new QXcbScreen(this, virtualDesktop, outputs[i], output.data());
siblings << screen;
- hasOutputs = true;
m_screens << screen;
// There can be multiple outputs per screen, use either
@@ -435,11 +466,22 @@ void QXcbConnection::initializeScreens()
}
}
}
+ virtualDesktop->setScreens(siblings);
}
}
}
}
- virtualDesktop->setScreens(siblings);
+ if (virtualDesktop->screens().isEmpty()) {
+ // If there are no XRandR outputs or XRandR extension is missing,
+ // then create a fake/legacy screen.
+ QXcbScreen *screen = new QXcbScreen(this, virtualDesktop, XCB_NONE, Q_NULLPTR);
+ m_screens << screen;
+ if (m_primaryScreenNumber == xcbScreenNumber) {
+ primaryScreen = screen;
+ primaryScreen->setPrimary(true);
+ }
+ virtualDesktop->addScreen(screen);
+ }
xcb_screen_next(&it);
++xcbScreenNumber;
} // for each xcb screen
@@ -447,39 +489,25 @@ void QXcbConnection::initializeScreens()
foreach (QXcbVirtualDesktop *virtualDesktop, m_virtualDesktops)
virtualDesktop->subscribeToXFixesSelectionNotify();
- // 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)
- QXcbVirtualDesktop *virtualDesktop = m_virtualDesktops.value(0);
- if (virtualDesktop && !hasOutputs && !virtualDesktop->size().isEmpty() && m_screens.isEmpty()) {
- QXcbScreen *screen = createScreen(virtualDesktop, 0, Q_NULLPTR);
- virtualDesktop->setScreens(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());
- if (m_screens.first() != primaryScreen) {
- m_screens.removeOne(primaryScreen);
- m_screens.prepend(primaryScreen);
+ if (m_virtualDesktops.isEmpty()) {
+ qFatal("QXcbConnection: no screens available");
+ } else {
+ // Ensure the primary screen is first on the list
+ if (primaryScreen) {
+ if (m_screens.first() != primaryScreen) {
+ m_screens.removeOne(primaryScreen);
+ m_screens.prepend(primaryScreen);
+ }
}
- }
- // Push the screens to QApplication
- QXcbIntegration *integration = QXcbIntegration::instance();
- foreach (QXcbScreen* screen, m_screens) {
- qCDebug(lcQpaScreen) << "adding" << screen << "(Primary:" << screen->isPrimary() << ')';
- integration->screenAdded(screen, screen->isPrimary());
- }
+ // Push the screens to QGuiApplication
+ foreach (QXcbScreen *screen, m_screens) {
+ qCDebug(lcQpaScreen) << "adding" << screen << "(Primary:" << screen->isPrimary() << ")";
+ QXcbIntegration::instance()->screenAdded(screen, screen->isPrimary());
+ }
- if (!m_screens.isEmpty())
qCDebug(lcQpaScreen) << "primary output is" << m_screens.first()->name();
+ }
}
QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGrabServer, xcb_visualid_t defaultVisualId, const char *displayName)
@@ -553,9 +581,6 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGra
initializeXFixes();
initializeScreens();
- if (m_screens.isEmpty())
- qFatal("QXcbConnection: no screens available");
-
initializeXRender();
m_xi2Enabled = false;
#if defined(XCB_USE_XINPUT2)
diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h
index 3c82170..fb7cc13 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.h
+++ b/src/plugins/platforms/xcb/qxcbconnection.h
@@ -518,15 +518,17 @@ private:
void initializeXShape();
void initializeXKB();
void handleClientMessageEvent(const xcb_client_message_event_t *event);
- QXcbScreen* createScreen(QXcbVirtualDesktop *virtualDesktop,
- xcb_randr_output_t outputId = XCB_NONE,
- xcb_randr_get_output_info_reply_t *output = 0);
QXcbScreen* findScreenForCrtc(xcb_window_t rootWindow, xcb_randr_crtc_t crtc);
QXcbScreen* findScreenForOutput(xcb_window_t rootWindow, xcb_randr_output_t output);
QXcbVirtualDesktop* virtualDesktopForRootWindow(xcb_window_t rootWindow);
+ void updateScreens(const xcb_randr_notify_event_t *event);
bool checkOutputIsPrimary(xcb_window_t rootWindow, xcb_randr_output_t output);
+ void updateScreen(QXcbScreen *screen, const xcb_randr_output_change_t &outputChange);
+ QXcbScreen *createScreen(QXcbVirtualDesktop *virtualDesktop,
+ const xcb_randr_output_change_t &outputChange,
+ xcb_randr_get_output_info_reply_t *outputInfo);
+ void destroyScreen(QXcbScreen *screen);
void initializeScreens();
- void updateScreens(const xcb_randr_notify_event_t *event);
bool compressEvent(xcb_generic_event_t *event, int currentIndex, QXcbEventArray *eventqueue) const;
bool m_xi2Enabled;
diff --git a/src/plugins/platforms/xcb/qxcbscreen.cpp b/src/plugins/platforms/xcb/qxcbscreen.cpp
index 2a53b18..bf3c0a6 100644
--- a/src/plugins/platforms/xcb/qxcbscreen.cpp
+++ b/src/plugins/platforms/xcb/qxcbscreen.cpp
@@ -81,6 +81,13 @@ void QXcbVirtualDesktop::addScreen(QPlatformScreen *s)
((QXcbScreen *) s)->isPrimary() ? m_screens.prepend(s) : m_screens.append(s);
}
+void QXcbVirtualDesktop::setPrimaryScreen(QPlatformScreen *s)
+{
+ const int idx = m_screens.indexOf(s);
+ Q_ASSERT(idx > -1);
+ m_screens.swap(0, idx);
+}
+
QXcbXSettings *QXcbVirtualDesktop::xSettings() const
{
if (!m_xSettings) {
@@ -149,16 +156,15 @@ void QXcbVirtualDesktop::updateWorkArea()
}
QXcbScreen::QXcbScreen(QXcbConnection *connection, QXcbVirtualDesktop *virtualDesktop,
- xcb_randr_output_t outputId, xcb_randr_get_output_info_reply_t *output,
- QString outputName)
+ xcb_randr_output_t outputId, xcb_randr_get_output_info_reply_t *output)
: QXcbObject(connection)
, m_virtualDesktop(virtualDesktop)
, m_output(outputId)
- , m_crtc(output ? output->crtc : 0)
+ , m_crtc(output ? output->crtc : XCB_NONE)
, m_mode(XCB_NONE)
, m_primary(false)
, m_rotation(XCB_RANDR_ROTATION_ROTATE_0)
- , m_outputName(outputName)
+ , m_outputName(getOutputName(output))
, m_outputSizeMillimeters(output ? QSize(output->mm_width, output->mm_height) : QSize())
, m_virtualSize(virtualDesktop->size())
, m_virtualSizeMillimeters(virtualDesktop->physicalSize())
@@ -268,6 +274,22 @@ QXcbScreen::~QXcbScreen()
delete m_cursor;
}
+QString QXcbScreen::getOutputName(xcb_randr_get_output_info_reply_t *outputInfo)
+{
+ QString name;
+ if (outputInfo) {
+ name = QString::fromUtf8((const char*)xcb_randr_get_output_info_name(outputInfo),
+ xcb_randr_get_output_info_name_length(outputInfo));
+ } else {
+ QByteArray displayName = connection()->displayName();
+ int dotPos = displayName.lastIndexOf('.');
+ if (dotPos != -1)
+ displayName.truncate(dotPos);
+ name = QString::fromLocal8Bit(displayName) + QLatin1Char('.')
+ + QString::number(m_virtualDesktop->number());
+ }
+ return name;
+}
QWindow *QXcbScreen::topLevelAt(const QPoint &p) const
{
@@ -392,6 +414,16 @@ QPlatformCursor *QXcbScreen::cursor() const
return m_cursor;
}
+void QXcbScreen::setOutput(xcb_randr_output_t outputId,
+ xcb_randr_get_output_info_reply_t *outputInfo)
+{
+ m_output = outputId;
+ m_crtc = outputInfo ? outputInfo->crtc : XCB_NONE;
+ m_mode = XCB_NONE;
+ m_outputName = getOutputName(outputInfo);
+ // TODO: Send an event to the QScreen instance that the screen changed its name
+}
+
/*!
\brief handle the XCB screen change event and update properties
@@ -460,19 +492,10 @@ void QXcbScreen::handleScreenChange(xcb_randr_screen_change_notify_event_t *chan
updateGeometry(change_event->timestamp);
- QWindowSystemInterface::handleScreenGeometryChange(QPlatformScreen::screen(), geometry(), availableGeometry());
QWindowSystemInterface::handleScreenOrientationChange(QPlatformScreen::screen(), m_orientation);
QDpi ldpi = logicalDpi();
QWindowSystemInterface::handleScreenLogicalDotsPerInchChange(QPlatformScreen::screen(), ldpi.first, ldpi.second);
-
- // Windows which had null screens have already had expose events by now.
- // They need to be told the screen is back, it's OK to render.
- foreach (QWindow *window, QGuiApplication::topLevelWindows()) {
- QXcbWindow *xcbWin = static_cast<QXcbWindow*>(window->handle());
- if (xcbWin)
- xcbWin->maybeSetScreen(this);
- }
}
void QXcbScreen::updateGeometry(xcb_timestamp_t timestamp)
diff --git a/src/plugins/platforms/xcb/qxcbscreen.h b/src/plugins/platforms/xcb/qxcbscreen.h
index c68c290..79620f4 100644
--- a/src/plugins/platforms/xcb/qxcbscreen.h
+++ b/src/plugins/platforms/xcb/qxcbscreen.h
@@ -72,6 +72,7 @@ public:
void setScreens(QList<QPlatformScreen *> sl) { m_screens = sl; }
void removeScreen(QPlatformScreen *s) { m_screens.removeOne(s); }
void addScreen(QPlatformScreen *s);
+ void setPrimaryScreen(QPlatformScreen *s);
QXcbXSettings *xSettings() const;
@@ -101,10 +102,11 @@ class Q_XCB_EXPORT QXcbScreen : public QXcbObject, public QPlatformScreen
{
public:
QXcbScreen(QXcbConnection *connection, QXcbVirtualDesktop *virtualDesktop,
- xcb_randr_output_t outputId, xcb_randr_get_output_info_reply_t *output,
- QString outputName);
+ xcb_randr_output_t outputId, xcb_randr_get_output_info_reply_t *outputInfo);
~QXcbScreen();
+ QString getOutputName(xcb_randr_get_output_info_reply_t *outputInfo);
+
QPixmap grabWindow(WId window, int x, int y, int width, int height) const Q_DECL_OVERRIDE;
QWindow *topLevelAt(const QPoint &point) const Q_DECL_OVERRIDE;
@@ -137,6 +139,10 @@ public:
xcb_randr_crtc_t crtc() const { return m_crtc; }
xcb_randr_mode_t mode() const { return m_mode; }
+ void setOutput(xcb_randr_output_t outputId,
+ xcb_randr_get_output_info_reply_t *outputInfo);
+ void setCrtc(xcb_randr_crtc_t crtc) { m_crtc = crtc; }
+
void windowShown(QXcbWindow *window);
QString windowManagerName() const { return m_windowManagerName; }
bool syncRequestSupported() const { return m_syncRequestSupported; }
diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp
index d0efb68..cbb67f0 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.cpp
+++ b/src/plugins/platforms/xcb/qxcbwindow.cpp
@@ -627,14 +627,6 @@ void QXcbWindow::destroy()
m_pendingSyncRequest->invalidate();
}
-void QXcbWindow::maybeSetScreen(QXcbScreen *screen)
-{
- if (!window()->screen() && screen->geometry().contains(geometry().topLeft())) {
- QWindowSystemInterface::handleWindowScreenChanged(window(), static_cast<QPlatformScreen *>(screen)->screen());
- QWindowSystemInterface::handleExposeEvent(window(), QRegion(QRect(QPoint(0, 0), window()->size())));
- }
-}
-
void QXcbWindow::setGeometry(const QRect &rect)
{
QPlatformWindow::setGeometry(rect);
@@ -850,15 +842,13 @@ void QXcbWindow::hide()
Q_XCB_CALL(xcb_unmap_window(xcb_connection(), m_window));
// send synthetic UnmapNotify event according to icccm 4.1.4
- if (xcbScreen()) {
- xcb_unmap_notify_event_t event;
- event.response_type = XCB_UNMAP_NOTIFY;
- event.event = xcbScreen()->root();
- event.window = m_window;
- event.from_configure = false;
- Q_XCB_CALL(xcb_send_event(xcb_connection(), false, xcbScreen()->root(),
- XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, (const char *)&event));
- }
+ xcb_unmap_notify_event_t event;
+ event.response_type = XCB_UNMAP_NOTIFY;
+ event.event = xcbScreen()->root();
+ event.window = m_window;
+ event.from_configure = false;
+ Q_XCB_CALL(xcb_send_event(xcb_connection(), false, xcbScreen()->root(),
+ XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, (const char *)&event));
xcb_flush(xcb_connection());
@@ -1186,8 +1176,6 @@ void QXcbWindow::changeNetWmState(bool set, xcb_atom_t one, xcb_atom_t two)
event.data.data32[3] = 0;
event.data.data32[4] = 0;
- if (!xcbScreen())
- return;
Q_XCB_CALL(xcb_send_event(xcb_connection(), 0, xcbScreen()->root(), XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, (const char *)&event));
}
@@ -1440,8 +1428,6 @@ void QXcbWindow::setParent(const QPlatformWindow *parent)
xcb_parent_id = qXcbParent->xcb_window();
m_embedded = qXcbParent->window()->type() == Qt::ForeignWindow;
} else {
- if (!xcbScreen())
- return;
xcb_parent_id = xcbScreen()->root();
m_embedded = false;
}
@@ -1997,7 +1983,7 @@ void QXcbWindow::handleConfigureNotifyEvent(const xcb_configure_notify_event_t *
{
bool fromSendEvent = (event->response_type & 0x80);
QPoint pos(event->x, event->y);
- if (!parent() && !fromSendEvent && xcbScreen()) {
+ if (!parent() && !fromSendEvent) {
// Do not trust the position, query it instead.
xcb_translate_coordinates_cookie_t cookie = xcb_translate_coordinates(xcb_connection(), xcb_window(),
xcbScreen()->root(), 0, 0);
@@ -2297,8 +2283,6 @@ void QXcbWindow::handleEnterNotifyEvent(const xcb_enter_notify_event_t *event)
return;
const QPoint local(event->event_x, event->event_y);
- if (!xcbScreen())
- return;
QPoint global = QPoint(event->root_x, event->root_y);
QWindowSystemInterface::handleEnterEvent(window(), local, global);
}
@@ -2316,8 +2300,6 @@ void QXcbWindow::handleLeaveNotifyEvent(const xcb_leave_notify_event_t *event)
if (enterWindow) {
QPoint local(enter->event_x, enter->event_y);
- if (!xcbScreen())
- return;
QPoint global = QPoint(event->root_x, event->root_y);
QWindowSystemInterface::handleEnterLeaveEvent(enterWindow->window(), window(), local, global);
@@ -2333,8 +2315,6 @@ void QXcbWindow::handlePropertyNotifyEvent(const xcb_property_notify_event_t *ev
connection()->setTime(event->time);
const bool propertyDeleted = event->state == XCB_PROPERTY_DELETE;
- if (!xcbScreen())
- return;
if (event->atom == atom(QXcbAtom::_NET_WM_STATE) || event->atom == atom(QXcbAtom::WM_STATE)) {
if (propertyDeleted)
@@ -2654,8 +2634,6 @@ bool QXcbWindow::needsSync() const
void QXcbWindow::postSyncWindowRequest()
{
- if (!xcbScreen())
- return;
if (!m_pendingSyncRequest) {
QXcbSyncWindowRequest *e = new QXcbSyncWindowRequest(this);
m_pendingSyncRequest = e;
diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h
index fd7d69c..4d7ea96 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.h
+++ b/src/plugins/platforms/xcb/qxcbwindow.h
@@ -167,7 +167,6 @@ public:
virtual void create();
virtual void destroy();
- void maybeSetScreen(QXcbScreen *screen);
QXcbScreen *screenForNativeGeometry(const QRect &newGeometry) const;
public Q_SLOTS:
--
2.5.0

View File

@ -1 +1 @@
687e2b122fa2c3390b5e20a166d38038 qtbase-opensource-src-5.5.1.tar.xz
42be7547996328b76998f89047f92c32 qtbase-opensource-src-5.6.0-beta2.tar.xz