crashes when connecting/disconnecting displays (#1083664,QTBUG-42985)

This commit is contained in:
Rex Dieter 2015-01-31 22:13:24 -06:00
parent dd0625c74f
commit a12aa064a0
2 changed files with 589 additions and 1 deletions

View File

@ -33,7 +33,7 @@
Summary: Qt5 - QtBase components
Name: qt5-qtbase
Version: 5.4.0
Release: 8%{?dist}
Release: 9%{?dist}
# See LGPL_EXCEPTIONS.txt, for exception details
License: LGPLv2 with exceptions or GPLv3 with exceptions
@ -78,6 +78,10 @@ Patch12: qtbase-opensource-src-5.2.0-enable_ft_lcdfilter.patch
# NEEDS REBASE
Patch50: qt5-poll.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=1083664
# https://bugreports.qt.io/browse/QTBUG-42985
Patch51: qtbase-opensource-src-5.4.0-QTBUG-42985.patch
## upstream patches
# workaround https://bugreports.qt-project.org/browse/QTBUG-43057
# 'make docs' crash on el6, use qSort instead of std::sort
@ -319,6 +323,7 @@ rm -fv mkspecs/linux-g++*/qmake.conf.multilib-optflags
%patch12 -p1 -b .enable_ft_lcdfilter
#patch50 -p1 -b .poll
%patch51 -p1 -b .QTBUG-42985
%if 0%{?rhel} == 6
%patch100 -p1 -b .QTBUG-43057
@ -826,6 +831,9 @@ fi
%changelog
* Sat Jan 31 2015 Rex Dieter <rdieter@fedoraproject.org> 5.4.0-9
- crashes when connecting/disconnecting displays (#1083664,QTBUG-42985)
* Tue Jan 27 2015 David Tardon <dtardon@redhat.com> - 5.4.0-8
- full build

View File

@ -0,0 +1,580 @@
--- qtbase-opensource-src-5.4.0/src/gui/kernel/qplatformintegration.cpp 2014-12-05 17:24:36.000000000 +0100
+++ qtbase-opensource-src-5.4.0/src/gui/kernel/qplatformintegration.cpp 2015-01-31 23:42:47.762253331 +0100
@@ -429,16 +429,40 @@ QList<int> QPlatformIntegration::possibl
This adds the screen to QGuiApplication::screens(), and emits the
QGuiApplication::screenAdded() signal.
+ If the added screen is a primary screen (isPrimary = true), it is prepended
+ to the QGuiApplicationPrivate::screen_list, since
+ QGuiApplication::primaryScreen always returns the first screen in the list.
+
The screen is automatically removed when the QPlatformScreen is destroyed.
*/
-void QPlatformIntegration::screenAdded(QPlatformScreen *ps)
+void QPlatformIntegration::screenAdded(QPlatformScreen *ps, bool isPrimary)
{
QScreen *screen = new QScreen(ps);
ps->d_func()->screen = screen;
- QGuiApplicationPrivate::screen_list << screen;
+ if (isPrimary) {
+ QGuiApplicationPrivate::screen_list.prepend(screen);
+ } else {
+ QGuiApplicationPrivate::screen_list.append(screen);
+ }
emit qGuiApp->screenAdded(screen);
}
+/*!
+ Should be called by the implementation whenever a screen is removed.
+
+ The implementation should ensure that the screen removed is not the
+ primary screen.
+*/
+void QPlatformIntegration::screenRemoved(QPlatformScreen *ps)
+{
+ if (ps->screen() == QGuiApplicationPrivate::screen_list.first()) {
+ qWarning("Primary screen removed, expect trouble");
+ }
+ if (QGuiApplicationPrivate::screen_list.removeOne(ps->screen()) && qApp) {
+ Q_EMIT qApp->screenRemoved(ps->screen());
+ }
+}
+
QStringList QPlatformIntegration::themeNames() const
{
return QStringList();
--- qtbase-opensource-src-5.4.0/src/gui/kernel/qplatformintegration.h 2014-12-05 17:24:36.000000000 +0100
+++ qtbase-opensource-src-5.4.0/src/gui/kernel/qplatformintegration.h 2015-01-31 20:15:58.620715451 +0100
@@ -169,7 +169,8 @@ public:
#endif
protected:
- void screenAdded(QPlatformScreen *screen);
+ void screenAdded(QPlatformScreen *screen, bool isPrimary = false);
+ void screenRemoved(QPlatformScreen *screen);
};
QT_END_NAMESPACE
--- qtbase-opensource-src-5.4.0/src/gui/kernel/qplatformscreen.cpp 2014-12-05 17:24:36.000000000 +0100
+++ qtbase-opensource-src-5.4.0/src/gui/kernel/qplatformscreen.cpp 2015-01-31 20:16:25.413205752 +0100
@@ -52,8 +52,6 @@ QPlatformScreen::QPlatformScreen()
QPlatformScreen::~QPlatformScreen()
{
Q_D(QPlatformScreen);
-
- QGuiApplicationPrivate::screen_list.removeOne(d->screen);
delete d->screen;
}
--- qtbase-opensource-src-5.4.0/src/gui/kernel/qscreen.cpp 2014-12-05 17:24:36.000000000 +0100
+++ qtbase-opensource-src-5.4.0/src/gui/kernel/qscreen.cpp 2015-01-31 19:30:45.295665651 +0100
@@ -66,16 +66,6 @@ QScreen::QScreen(QPlatformScreen *screen
{
}
-
-/*!
- Destroys the screen.
- */
-QScreen::~QScreen()
-{
- if (qApp)
- Q_EMIT qApp->screenRemoved(this);
-}
-
/*!
Get the platform screen handle.
*/
--- qtbase-opensource-src-5.4.0/src/gui/kernel/qscreen.h 2014-12-05 17:24:36.000000000 +0100
+++ qtbase-opensource-src-5.4.0/src/gui/kernel/qscreen.h 2015-01-31 19:30:39.204553634 +0100
@@ -81,7 +81,6 @@ class Q_GUI_EXPORT QScreen : public QObj
Q_PROPERTY(qreal refreshRate READ refreshRate NOTIFY refreshRateChanged)
public:
- ~QScreen();
QPlatformScreen *handle() const;
QString name() const;
--- qtbase-opensource-src-5.4.0/src/plugins/platforms/xcb/qxcbclipboard.cpp 2014-12-05 17:24:37.000000000 +0100
+++ qtbase-opensource-src-5.4.0/src/plugins/platforms/xcb/qxcbclipboard.cpp 2015-01-31 15:25:10.611111149 +0100
@@ -276,7 +276,7 @@ QXcbClipboard::QXcbClipboard(QXcbConnect
m_timestamp[QClipboard::Clipboard] = XCB_CURRENT_TIME;
m_timestamp[QClipboard::Selection] = XCB_CURRENT_TIME;
- m_screen = connection()->primaryScreen();
+ QXcbScreen * screen = connection()->primaryScreen();
int x = 0, y = 0, w = 3, h = 3;
@@ -284,11 +284,11 @@ QXcbClipboard::QXcbClipboard(QXcbConnect
Q_XCB_CALL(xcb_create_window(xcb_connection(),
XCB_COPY_FROM_PARENT, // depth -- same as root
m_owner, // window id
- m_screen->screen()->root, // parent window id
+ screen->screen()->root, // parent window id
x, y, w, h,
0, // border width
XCB_WINDOW_CLASS_INPUT_OUTPUT, // window class
- m_screen->screen()->root_visual, // visual
+ screen->screen()->root_visual, // visual
0, // value mask
0)); // value list
#ifndef QT_NO_DEBUG
@@ -462,8 +462,15 @@ bool QXcbClipboard::ownsMode(QClipboard:
return m_timestamp[mode] != XCB_CURRENT_TIME;
}
+QXcbScreen *QXcbClipboard::screen() const
+{
+ return connection()->primaryScreen();
+}
+
xcb_window_t QXcbClipboard::requestor() const
{
+ QXcbScreen * screen = connection()->primaryScreen();
+
if (!m_requestor) {
const int x = 0, y = 0, w = 3, h = 3;
QXcbClipboard *that = const_cast<QXcbClipboard *>(this);
@@ -472,11 +479,11 @@ xcb_window_t QXcbClipboard::requestor()
Q_XCB_CALL(xcb_create_window(xcb_connection(),
XCB_COPY_FROM_PARENT, // depth -- same as root
window, // window id
- m_screen->screen()->root, // parent window id
+ screen->screen()->root, // parent window id
x, y, w, h,
0, // border width
XCB_WINDOW_CLASS_INPUT_OUTPUT, // window class
- m_screen->screen()->root_visual, // visual
+ screen->screen()->root_visual, // visual
0, // value mask
0)); // value list
#ifndef QT_NO_DEBUG
--- qtbase-opensource-src-5.4.0/src/plugins/platforms/xcb/qxcbclipboard.h 2014-12-05 17:24:37.000000000 +0100
+++ qtbase-opensource-src-5.4.0/src/plugins/platforms/xcb/qxcbclipboard.h 2015-01-31 15:24:53.881807083 +0100
@@ -59,7 +59,7 @@ public:
bool supportsMode(QClipboard::Mode mode) const;
bool ownsMode(QClipboard::Mode mode) const;
- QXcbScreen *screen() const { return m_screen; }
+ QXcbScreen *screen() const;
xcb_window_t requestor() const;
void setRequestor(xcb_window_t window);
@@ -91,8 +91,6 @@ private:
xcb_atom_t atomForMode(QClipboard::Mode mode) const;
QClipboard::Mode modeForAtom(xcb_atom_t atom) const;
- QXcbScreen *m_screen;
-
// Selection and Clipboard
QXcbClipboardMime *m_xClipboard[2];
QMimeData *m_clientClipboard[2];
--- qtbase-opensource-src-5.4.0/src/plugins/platforms/xcb/qxcbconnection.cpp 2014-12-05 17:24:37.000000000 +0100
+++ qtbase-opensource-src-5.4.0/src/plugins/platforms/xcb/qxcbconnection.cpp 2015-01-31 20:19:49.394941407 +0100
@@ -182,7 +182,6 @@ QXcbScreen* QXcbConnection::findOrCreate
void QXcbConnection::updateScreens()
{
xcb_screen_iterator_t it = xcb_setup_roots_iterator(m_setup);
- int screenNumber = 0; // index of this QScreen in QGuiApplication::screens()
int xcbScreenNumber = 0; // screen number in the xcb sense
QSet<QXcbScreen *> activeScreens;
QList<QXcbScreen *> newScreens;
@@ -194,7 +193,7 @@ void QXcbConnection::updateScreens()
// which will become virtual siblings.
xcb_screen_t *xcbScreen = it.data;
QList<QPlatformScreen *> siblings;
- int outputCount = 0;
+ int outputCount = 0, connectedOutputCount = 0;
if (has_randr_extension) {
xcb_generic_error_t *error = NULL;
xcb_randr_get_output_primary_cookie_t primaryCookie =
@@ -239,7 +238,7 @@ void QXcbConnection::updateScreens()
QXcbScreen *screen = findOrCreateScreen(newScreens, xcbScreenNumber, xcbScreen, output);
siblings << screen;
activeScreens << screen;
- ++screenNumber;
+ ++connectedOutputCount;
// There can be multiple outputs per screen, use either
// the first or an exact match. An exact match isn't
// always available if primary->output is XCB_NONE
@@ -262,7 +261,7 @@ void QXcbConnection::updateScreens()
}
// If there's no randr extension, or there was some error above, or the screen
// doesn't have outputs for some other reason (e.g. on VNC or ssh -X), just assume there is one screen.
- if (outputCount == 0) {
+ if (connectedOutputCount == 0) {
#ifdef Q_XCB_DEBUG
qDebug("Found a screen with zero outputs");
#endif
@@ -271,7 +270,6 @@ void QXcbConnection::updateScreens()
activeScreens << screen;
if (!primaryScreen)
primaryScreen = screen;
- ++screenNumber;
}
foreach (QPlatformScreen* s, siblings)
((QXcbScreen*)s)->setVirtualSiblings(siblings);
@@ -279,28 +277,39 @@ void QXcbConnection::updateScreens()
++xcbScreenNumber;
} // for each xcb screen
- // Now activeScreens is the complete set of screens which are active at this time.
- // Delete any existing screens which are not in activeScreens
+ // Rebuild screen list, ensuring primary screen is always in front,
+ // both in the QXcbConnection::m_screens list as well as in the
+ // QGuiApplicationPrivate::screen_list list, which gets updated via
+ // - screen added: ((QXcbIntegration*)QGuiApplicationPrivate::platformIntegration())->screenAdded();
+ // - screen removed: QPlatformScreen::~QPlatformScreen() via QXcbScreen::~QXcbScreen()
+
+ // Gather screens to delete
+ QList<QXcbScreen*> screensToDelete;
for (int i = m_screens.count() - 1; i >= 0; --i) {
if (!activeScreens.contains(m_screens[i])) {
- delete m_screens[i];
- m_screens.removeAt(i);
+ screensToDelete.append(m_screens.takeAt(i));
}
}
- // Add any new screens, and make sure the primary screen comes first
- // since it is used by QGuiApplication::primaryScreen()
+ // If there is a new primary screen, add that one first
+ if (newScreens.contains(primaryScreen)) {
+ newScreens.removeOne(primaryScreen);
+
+ m_screens.prepend(primaryScreen);
+ ((QXcbIntegration*)QGuiApplicationPrivate::platformIntegration())->screenAdded(primaryScreen, true);
+ }
+
+ // Add the remaining new screens
foreach (QXcbScreen* screen, newScreens) {
- if (screen == primaryScreen)
- m_screens.prepend(screen);
- else
- m_screens.append(screen);
+ m_screens.append(screen);
+ ((QXcbIntegration*)QGuiApplicationPrivate::platformIntegration())->screenAdded(screen);
}
- // Now that they are in the right order, emit the added signals for new screens only
- foreach (QXcbScreen* screen, m_screens)
- if (newScreens.contains(screen))
- ((QXcbIntegration*)QGuiApplicationPrivate::platformIntegration())->screenAdded(screen);
+ // And finally, delete the old screens, now that the new ones were added and we are sure that there is at least one screen available
+ foreach (QXcbScreen* screen, screensToDelete) {
+ ((QXcbIntegration*)QGuiApplicationPrivate::platformIntegration())->screenRemoved(screen);
+ delete screen;
+ }
}
QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGrabServer, const char *displayName)
--- qtbase-opensource-src-5.4.0/src/plugins/platforms/xcb/qxcbwindow.cpp 2014-12-05 17:24:37.000000000 +0100
+++ qtbase-opensource-src-5.4.0/src/plugins/platforms/xcb/qxcbwindow.cpp 2015-01-31 23:42:36.248036556 +0100
@@ -241,9 +241,7 @@ QXcbWindow::QXcbWindow(QWindow *window)
, m_syncState(NoSyncNeeded)
, m_pendingSyncRequest(0)
{
- m_screen = static_cast<QXcbScreen *>(window->screen()->handle());
-
- setConnection(m_screen->connection());
+ setConnection(xcbscreen()->connection());
if (window->type() != Qt::ForeignWindow)
create();
@@ -282,11 +280,13 @@ void QXcbWindow::create()
Qt::WindowType type = window()->type();
+ QXcbScreen* screen = this->xcbscreen();
+
if (type == Qt::Desktop) {
- m_window = m_screen->root();
- m_depth = m_screen->screen()->root_depth;
- m_visualId = m_screen->screen()->root_visual;
- const xcb_visualtype_t *visual = m_screen->visualForId(m_visualId);
+ m_window = screen->root();
+ m_depth = screen->screen()->root_depth;
+ m_visualId = screen->screen()->root_visual;
+ const xcb_visualtype_t *visual = screen->visualForId(m_visualId);
m_imageFormat = imageFormatForVisual(m_depth, visual->red_mask, visual->blue_mask);
connection()->addWindowEventListener(m_window, this);
return;
@@ -327,7 +327,7 @@ void QXcbWindow::create()
rect.setHeight(defaultWindowHeight);
}
- xcb_window_t xcb_parent_id = m_screen->root();
+ xcb_window_t xcb_parent_id = screen->root();
if (parent()) {
xcb_parent_id = static_cast<QXcbWindow *>(parent())->xcb_window();
m_embedded = parent()->window()->type() == Qt::ForeignWindow;
@@ -342,7 +342,7 @@ void QXcbWindow::create()
#if (defined(XCB_USE_GLX) || defined(XCB_USE_EGL)) && defined(XCB_USE_XLIB)
if (QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::OpenGL)) {
#if defined(XCB_USE_GLX)
- XVisualInfo *visualInfo = qglx_findVisualInfo(DISPLAY_FROM_XCB(m_screen), m_screen->screenNumber(), &m_format);
+ XVisualInfo *visualInfo = qglx_findVisualInfo(DISPLAY_FROM_XCB(screen), screen->screenNumber(), &m_format);
#elif defined(XCB_USE_EGL)
EGLDisplay eglDisplay = connection()->egl_display();
EGLConfig eglConfig = q_configFromGLFormat(eglDisplay, m_format, true);
@@ -371,8 +371,8 @@ void QXcbWindow::create()
Colormap cmap = XCreateColormap(DISPLAY_FROM_XCB(this), xcb_parent_id, visualInfo->visual, AllocNone);
XSetWindowAttributes a;
- a.background_pixel = WhitePixel(DISPLAY_FROM_XCB(this), m_screen->screenNumber());
- a.border_pixel = BlackPixel(DISPLAY_FROM_XCB(this), m_screen->screenNumber());
+ a.background_pixel = WhitePixel(DISPLAY_FROM_XCB(this), screen->screenNumber());
+ a.border_pixel = BlackPixel(DISPLAY_FROM_XCB(this), screen->screenNumber());
a.colormap = cmap;
m_visualId = visualInfo->visualid;
@@ -391,14 +391,14 @@ void QXcbWindow::create()
#endif //defined(XCB_USE_GLX) || defined(XCB_USE_EGL)
{
m_window = xcb_generate_id(xcb_connection());
- m_visualId = m_screen->screen()->root_visual;
- m_depth = m_screen->screen()->root_depth;
+ m_visualId = screen->screen()->root_visual;
+ m_depth = screen->screen()->root_depth;
uint32_t mask = 0;
uint32_t values[3];
if (m_format.alphaBufferSize() == 8) {
- xcb_depth_iterator_t depthIter = xcb_screen_allowed_depths_iterator(m_screen->screen());
+ xcb_depth_iterator_t depthIter = xcb_screen_allowed_depths_iterator(screen->screen());
while (depthIter.rem) {
if (depthIter.data->depth == 32) {
xcb_visualtype_iterator_t visualIter = xcb_depth_visuals_iterator(depthIter.data);
@@ -409,8 +409,8 @@ void QXcbWindow::create()
xcb_create_colormap(xcb_connection(), XCB_COLORMAP_ALLOC_NONE, colormap,
xcb_parent_id, m_visualId);
mask |= XCB_CW_BACK_PIXEL | XCB_CW_BORDER_PIXEL | XCB_CW_COLORMAP;
- values[0] = m_screen->screen()->white_pixel;
- values[1] = m_screen->screen()->black_pixel;
+ values[0] = screen->screen()->white_pixel;
+ values[1] = screen->screen()->black_pixel;
values[2] = colormap;
break;
}
@@ -419,7 +419,7 @@ void QXcbWindow::create()
}
}
- const xcb_visualtype_t *visual = m_screen->visualForId(m_visualId);
+ const xcb_visualtype_t *visual = screen->visualForId(m_visualId);
m_imageFormat = imageFormatForVisual(m_depth, visual->red_mask, visual->blue_mask);
Q_XCB_CALL(xcb_create_window(xcb_connection(),
@@ -449,7 +449,7 @@ void QXcbWindow::create()
properties[propertyCount++] = atom(QXcbAtom::WM_TAKE_FOCUS);
properties[propertyCount++] = atom(QXcbAtom::_NET_WM_PING);
- m_usingSyncProtocol = m_screen->syncRequestSupported();
+ m_usingSyncProtocol = screen->syncRequestSupported();
#if !defined(XCB_USE_GLX)
// synced resize only implemented on GLX
if (window()->supportsOpenGL())
@@ -508,7 +508,7 @@ void QXcbWindow::create()
xcb_set_wm_hints(xcb_connection(), m_window, &hints);
- xcb_window_t leader = m_screen->clientLeader();
+ xcb_window_t leader = screen->clientLeader();
Q_XCB_CALL(xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, m_window,
atom(QXcbAtom::WM_CLIENT_LEADER), XCB_ATOM_WINDOW, 32,
1, &leader));
@@ -534,7 +534,7 @@ void QXcbWindow::create()
#ifdef XCB_USE_XLIB
// force sync to read outstanding requests - see QTBUG-29106
- XSync(DISPLAY_FROM_XCB(m_screen), false);
+ XSync(DISPLAY_FROM_XCB(screen), false);
#endif
#ifndef QT_NO_DRAGANDDROP
@@ -728,7 +728,7 @@ void QXcbWindow::show()
// Default to client leader if there is no transient parent, else modal dialogs can
// be hidden by their parents.
if (!transientXcbParent)
- transientXcbParent = static_cast<QXcbScreen *>(screen())->clientLeader();
+ transientXcbParent = static_cast<QXcbScreen *>(xcbscreen())->clientLeader();
if (transientXcbParent) { // ICCCM 4.1.2.6
Q_XCB_CALL(xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, m_window,
XCB_ATOM_WM_TRANSIENT_FOR, XCB_ATOM_WINDOW, 32,
@@ -756,7 +756,7 @@ void QXcbWindow::show()
if (QGuiApplication::modalWindow() == window())
requestActivateWindow();
- m_screen->windowShown(this);
+ xcbscreen()->windowShown(this);
connection()->sync();
}
@@ -768,10 +768,10 @@ void QXcbWindow::hide()
// send synthetic UnmapNotify event according to icccm 4.1.4
xcb_unmap_notify_event_t event;
event.response_type = XCB_UNMAP_NOTIFY;
- event.event = m_screen->root();
+ event.event = xcbscreen()->root();
event.window = m_window;
event.from_configure = false;
- Q_XCB_CALL(xcb_send_event(xcb_connection(), false, m_screen->root(),
+ 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());
@@ -1091,7 +1091,7 @@ void QXcbWindow::changeNetWmState(bool s
event.data.data32[3] = 0;
event.data.data32[4] = 0;
- Q_XCB_CALL(xcb_send_event(xcb_connection(), 0, m_screen->root(), XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, (const char *)&event));
+ Q_XCB_CALL(xcb_send_event(xcb_connection(), 0, xcbscreen()->root(), XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, (const char *)&event));
}
void QXcbWindow::setWindowState(Qt::WindowState state)
@@ -1132,7 +1132,7 @@ void QXcbWindow::setWindowState(Qt::Wind
event.data.data32[3] = 0;
event.data.data32[4] = 0;
- Q_XCB_CALL(xcb_send_event(xcb_connection(), 0, m_screen->root(), XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, (const char *)&event));
+ Q_XCB_CALL(xcb_send_event(xcb_connection(), 0, xcbscreen()->root(), XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, (const char *)&event));
}
break;
case Qt::WindowMaximized:
@@ -1375,7 +1375,7 @@ void QXcbWindow::setParent(const QPlatfo
xcb_parent_id = qXcbParent->xcb_window();
m_embedded = qXcbParent->window()->type() == Qt::ForeignWindow;
} else {
- xcb_parent_id = m_screen->root();
+ xcb_parent_id = xcbscreen()->root();
m_embedded = false;
}
Q_XCB_CALL(xcb_reparent_window(xcb_connection(), xcb_window(), xcb_parent_id, topLeft.x(), topLeft.y()));
@@ -1543,7 +1543,7 @@ void QXcbWindow::requestActivateWindow()
event.data.data32[3] = 0;
event.data.data32[4] = 0;
- Q_XCB_CALL(xcb_send_event(xcb_connection(), 0, m_screen->root(), XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, (const char *)&event));
+ Q_XCB_CALL(xcb_send_event(xcb_connection(), 0, xcbscreen()->root(), XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, (const char *)&event));
} else {
Q_XCB_CALL(xcb_set_input_focus(xcb_connection(), XCB_INPUT_FOCUS_PARENT, m_window, connection()->time()));
}
@@ -1780,15 +1780,15 @@ void QXcbWindow::handleClientMessageEven
relayFocusToModalWindow();
return;
} else if (event->data.data32[0] == atom(QXcbAtom::_NET_WM_PING)) {
- if (event->window == m_screen->root())
+ if (event->window == xcbscreen()->root())
return;
xcb_client_message_event_t reply = *event;
reply.response_type = XCB_CLIENT_MESSAGE;
- reply.window = m_screen->root();
+ reply.window = xcbscreen()->root();
- xcb_send_event(xcb_connection(), 0, m_screen->root(), XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, (const char *)&reply);
+ xcb_send_event(xcb_connection(), 0, xcbscreen()->root(), XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, (const char *)&reply);
xcb_flush(xcb_connection());
} else if (event->data.data32[0] == atom(QXcbAtom::_NET_WM_SYNC_REQUEST)) {
connection()->setTime(event->data.data32[1]);
@@ -1838,7 +1838,7 @@ void QXcbWindow::handleConfigureNotifyEv
if (!parent() && !fromSendEvent) {
// Do not trust the position, query it instead.
xcb_translate_coordinates_cookie_t cookie = xcb_translate_coordinates(xcb_connection(), xcb_window(),
- m_screen->root(), 0, 0);
+ xcbscreen()->root(), 0, 0);
xcb_translate_coordinates_reply_t *reply = xcb_translate_coordinates_reply(xcb_connection(), cookie, NULL);
if (reply) {
pos.setX(reply->dst_x);
@@ -1853,8 +1853,7 @@ void QXcbWindow::handleConfigureNotifyEv
QWindowSystemInterface::handleGeometryChange(window(), rect);
QPlatformScreen *newScreen = screenForGeometry(rect);
- if (newScreen != m_screen) {
- m_screen = static_cast<QXcbScreen*>(newScreen);
+ if (newScreen != screen()) {
QWindowSystemInterface::handleWindowScreenChanged(window(), newScreen->screen());
}
@@ -1892,7 +1891,7 @@ QPoint QXcbWindow::mapToGlobal(const QPo
const int dpr = int(devicePixelRatio());
QPoint ret;
xcb_translate_coordinates_cookie_t cookie =
- xcb_translate_coordinates(xcb_connection(), xcb_window(), m_screen->root(),
+ xcb_translate_coordinates(xcb_connection(), xcb_window(), xcbscreen()->root(),
pos.x() * dpr, pos.y() * dpr);
xcb_translate_coordinates_reply_t *reply =
xcb_translate_coordinates_reply(xcb_connection(), cookie, NULL);
@@ -1913,7 +1912,7 @@ QPoint QXcbWindow::mapFromGlobal(const Q
const int dpr = int(devicePixelRatio());
QPoint ret;
xcb_translate_coordinates_cookie_t cookie =
- xcb_translate_coordinates(xcb_connection(), m_screen->root(), xcb_window(),
+ xcb_translate_coordinates(xcb_connection(), xcbscreen()->root(), xcb_window(),
pos.x() *dpr, pos.y() * dpr);
xcb_translate_coordinates_reply_t *reply =
xcb_translate_coordinates_reply(xcb_connection(), cookie, NULL);
@@ -2136,8 +2135,8 @@ void QXcbWindow::handlePropertyNotifyEve
m_windowState = newState;
}
return;
- } else if (event->atom == atom(QXcbAtom::_NET_WORKAREA) && event->window == m_screen->root()) {
- m_screen->updateGeometry(event->time);
+ } else if (event->atom == atom(QXcbAtom::_NET_WORKAREA) && event->window == xcbscreen()->root()) {
+ xcbscreen()->updateGeometry(event->time);
}
}
@@ -2260,7 +2259,7 @@ bool QXcbWindow::startSystemResize(const
xev.data.data32[3] = XCB_BUTTON_INDEX_1;
xev.data.data32[4] = 0;
xcb_ungrab_pointer(connection()->xcb_connection(), XCB_CURRENT_TIME);
- xcb_send_event(connection()->xcb_connection(), false, m_screen->root(),
+ xcb_send_event(connection()->xcb_connection(), false, xcbscreen()->root(),
XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT | XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY,
(const char *)&xev);
return true;
@@ -2396,13 +2395,18 @@ void QXcbWindow::postSyncWindowRequest()
if (!m_pendingSyncRequest) {
QXcbSyncWindowRequest *e = new QXcbSyncWindowRequest(this);
m_pendingSyncRequest = e;
- QCoreApplication::postEvent(m_screen->connection(), e);
+ QCoreApplication::postEvent(xcbscreen()->connection(), e);
}
}
qreal QXcbWindow::devicePixelRatio() const
{
- return m_screen ? m_screen->devicePixelRatio() : 1.0;
+ return xcbscreen() ? xcbscreen()->devicePixelRatio() : 1.0;
+}
+
+QXcbScreen *QXcbWindow::xcbscreen() const
+{
+ return static_cast<QXcbScreen *>(screen());
}
QT_END_NAMESPACE
--- qtbase-opensource-src-5.4.0/src/plugins/platforms/xcb/qxcbwindow.h 2014-12-05 17:24:37.000000000 +0100
+++ qtbase-opensource-src-5.4.0/src/plugins/platforms/xcb/qxcbwindow.h 2015-01-31 23:25:18.560692091 +0100
@@ -152,6 +152,8 @@ public:
void postSyncWindowRequest();
void clearSyncWindowRequest() { m_pendingSyncRequest = 0; }
+ QXcbScreen *xcbscreen() const;
+
qreal devicePixelRatio() const;
public Q_SLOTS:
@@ -186,8 +188,6 @@ private:
void doFocusIn();
void doFocusOut();
- QXcbScreen *m_screen;
-
xcb_window_t m_window;
uint m_depth;