diff --git a/src/gui/kernel/qplatformintegration.cpp b/src/gui/kernel/qplatformintegration.cpp index 39b031e..7f808da 100644 --- a/src/gui/kernel/qplatformintegration.cpp +++ b/src/gui/kernel/qplatformintegration.cpp @@ -429,16 +429,40 @@ QList QPlatformIntegration::possibleKeys(const QKeyEvent *) const 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(); diff --git a/src/gui/kernel/qplatformintegration.h b/src/gui/kernel/qplatformintegration.h index d510240..5ec7896 100644 --- a/src/gui/kernel/qplatformintegration.h +++ b/src/gui/kernel/qplatformintegration.h @@ -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 diff --git a/src/gui/kernel/qplatformscreen.cpp b/src/gui/kernel/qplatformscreen.cpp index 71710d1..4fb7114 100644 --- a/src/gui/kernel/qplatformscreen.cpp +++ b/src/gui/kernel/qplatformscreen.cpp @@ -52,8 +52,6 @@ QPlatformScreen::QPlatformScreen() QPlatformScreen::~QPlatformScreen() { Q_D(QPlatformScreen); - - QGuiApplicationPrivate::screen_list.removeOne(d->screen); delete d->screen; } diff --git a/src/gui/kernel/qscreen.cpp b/src/gui/kernel/qscreen.cpp index ed6e8dd..8909eed 100644 --- a/src/gui/kernel/qscreen.cpp +++ b/src/gui/kernel/qscreen.cpp @@ -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. */ diff --git a/src/gui/kernel/qscreen.h b/src/gui/kernel/qscreen.h index 766b3d8..144730a 100644 --- a/src/gui/kernel/qscreen.h +++ b/src/gui/kernel/qscreen.h @@ -81,7 +81,6 @@ class Q_GUI_EXPORT QScreen : public QObject Q_PROPERTY(qreal refreshRate READ refreshRate NOTIFY refreshRateChanged) public: - ~QScreen(); QPlatformScreen *handle() const; QString name() const; diff --git a/src/plugins/platforms/xcb/qxcbclipboard.cpp b/src/plugins/platforms/xcb/qxcbclipboard.cpp index 4b6caa9..4c2be75 100644 --- a/src/plugins/platforms/xcb/qxcbclipboard.cpp +++ b/src/plugins/platforms/xcb/qxcbclipboard.cpp @@ -276,7 +276,7 @@ QXcbClipboard::QXcbClipboard(QXcbConnection *c) 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(QXcbConnection *c) 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::Mode mode) const 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(this); @@ -472,11 +479,11 @@ xcb_window_t QXcbClipboard::requestor() const 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 diff --git a/src/plugins/platforms/xcb/qxcbclipboard.h b/src/plugins/platforms/xcb/qxcbclipboard.h index e76d502..b6cbda4 100644 --- a/src/plugins/platforms/xcb/qxcbclipboard.h +++ b/src/plugins/platforms/xcb/qxcbclipboard.h @@ -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]; diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp index 77e4601..a2177d2 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection.cpp @@ -182,7 +182,6 @@ QXcbScreen* QXcbConnection::findOrCreateScreen(QList& newScreens, 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 activeScreens; QList newScreens; @@ -194,7 +193,7 @@ void QXcbConnection::updateScreens() // which will become virtual siblings. xcb_screen_t *xcbScreen = it.data; QList 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 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) diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index c0076a9..abb945c 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -257,9 +257,7 @@ QXcbWindow::QXcbWindow(QWindow *window) , m_syncState(NoSyncNeeded) , m_pendingSyncRequest(0) { - m_screen = static_cast(window->screen()->handle()); - - setConnection(m_screen->connection()); + setConnection(xcbscreen()->connection()); if (window->type() != Qt::ForeignWindow) create(); @@ -298,11 +296,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; @@ -338,7 +338,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(parent())->xcb_window(); m_embedded = parent()->window()->type() == Qt::ForeignWindow; @@ -353,7 +353,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); @@ -382,8 +382,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; @@ -402,14 +402,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); @@ -420,8 +420,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; } @@ -430,7 +430,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(), @@ -460,7 +460,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()) @@ -519,7 +519,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)); @@ -545,7 +545,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 @@ -742,7 +742,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(screen())->clientLeader(); + transientXcbParent = static_cast(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, @@ -773,7 +773,7 @@ void QXcbWindow::show() if (QGuiApplication::modalWindow() == window()) requestActivateWindow(); - m_screen->windowShown(this); + xcbscreen()->windowShown(this); connection()->sync(); } @@ -785,10 +785,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()); @@ -1108,7 +1108,7 @@ void QXcbWindow::changeNetWmState(bool set, xcb_atom_t one, xcb_atom_t two) 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) @@ -1149,7 +1149,7 @@ void QXcbWindow::setWindowState(Qt::WindowState state) 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: @@ -1392,7 +1392,7 @@ void QXcbWindow::setParent(const QPlatformWindow *parent) 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())); @@ -1560,7 +1560,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())); } @@ -1797,15 +1797,15 @@ void QXcbWindow::handleClientMessageEvent(const xcb_client_message_event_t *even 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]); @@ -1872,7 +1872,7 @@ void QXcbWindow::handleConfigureNotifyEvent(const xcb_configure_notify_event_t * 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); @@ -1889,8 +1889,7 @@ void QXcbWindow::handleConfigureNotifyEvent(const xcb_configure_notify_event_t * QWindowSystemInterface::handleGeometryChange(window(), rect); QPlatformScreen *newScreen = screenForNativeGeometry(nativeRect); - if (newScreen != m_screen) { - m_screen = static_cast(newScreen); + if (newScreen != screen()) { QWindowSystemInterface::handleWindowScreenChanged(window(), newScreen->screen()); int newDpr = devicePixelRatio(); if (newDpr != dpr) { @@ -1934,7 +1933,7 @@ QPoint QXcbWindow::mapToGlobal(const QPoint &pos) const 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); @@ -1955,7 +1954,7 @@ QPoint QXcbWindow::mapFromGlobal(const QPoint &pos) const 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); @@ -2179,8 +2178,8 @@ void QXcbWindow::handlePropertyNotifyEvent(const xcb_property_notify_event_t *ev 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); } } @@ -2309,7 +2308,7 @@ bool QXcbWindow::startSystemResize(const QPoint &pos, Qt::Corner corner) 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; @@ -2354,7 +2353,7 @@ void QXcbWindow::handleXEmbedMessage(const xcb_client_message_event_t *event) break; case XEMBED_EMBEDDED_NOTIFY: Q_XCB_CALL(xcb_map_window(xcb_connection(), m_window)); - m_screen->windowShown(this); + xcbscreen()->windowShown(this); break; case XEMBED_FOCUS_IN: Qt::FocusReason reason; @@ -2448,13 +2447,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(screen()); } QT_END_NAMESPACE diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h index 254421e..966a834 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.h +++ b/src/plugins/platforms/xcb/qxcbwindow.h @@ -152,6 +152,8 @@ public: void postSyncWindowRequest(); void clearSyncWindowRequest() { m_pendingSyncRequest = 0; } + QXcbScreen *xcbscreen() const; + qreal devicePixelRatio() const; QPlatformScreen *screenForNativeGeometry(const QRect &newGeometry) const; @@ -188,8 +190,6 @@ private: void doFocusIn(); void doFocusOut(); - QXcbScreen *m_screen; - xcb_window_t m_window; uint m_depth;