diff options
author | Frederik Gladhorn <frederik.gladhorn@digia.com> | 2013-03-06 00:11:52 +0100 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-03-06 00:11:52 +0100 |
commit | b86106387350f673a20d3b0a2413023f6205169b (patch) | |
tree | 2dfc079f1eecbbf9fde8733430a3a1e2f04d9a42 /src/plugins | |
parent | 88918abddeb323340c4a49dda035898a740373da (diff) | |
parent | 5e8ae03578ecd0538a774505f2f7e2fc626b0ab7 (diff) |
Merge "Merge remote-tracking branch 'origin/stable' into dev" into refs/staging/dev
Diffstat (limited to 'src/plugins')
23 files changed, 249 insertions, 283 deletions
diff --git a/src/plugins/bearer/connman/qconnmanengine.cpp b/src/plugins/bearer/connman/qconnmanengine.cpp index 2b28cdbf61..589b0e2c24 100644 --- a/src/plugins/bearer/connman/qconnmanengine.cpp +++ b/src/plugins/bearer/connman/qconnmanengine.cpp @@ -159,7 +159,7 @@ void QConnmanEngine::connectToId(const QString &id) QOfonoDataConnectionManagerInterface dc(modemPath,0); foreach (const QDBusObjectPath &dcPath,dc.getPrimaryContexts()) { if(dcPath.path().contains(servicePath.section("_",-1))) { - QOfonoPrimaryDataContextInterface primaryContext(dcPath.path(),0); + QOfonoConnectionContextInterface primaryContext(dcPath.path(),0); primaryContext.setActive(true); } } @@ -183,7 +183,7 @@ void QConnmanEngine::disconnectFromId(const QString &id) QOfonoDataConnectionManagerInterface dc(modemPath,0); foreach (const QDBusObjectPath &dcPath,dc.getPrimaryContexts()) { if(dcPath.path().contains(servicePath.section("_",-1))) { - QOfonoPrimaryDataContextInterface primaryContext(dcPath.path(),0); + QOfonoConnectionContextInterface primaryContext(dcPath.path(),0); primaryContext.setActive(false); } } diff --git a/src/plugins/bearer/connman/qofonoservice_linux.cpp b/src/plugins/bearer/connman/qofonoservice_linux.cpp index f6fb55522e..1983276d94 100644 --- a/src/plugins/bearer/connman/qofonoservice_linux.cpp +++ b/src/plugins/bearer/connman/qofonoservice_linux.cpp @@ -108,7 +108,7 @@ QDBusObjectPath QOfonoManagerInterface::currentModem() foreach (const QDBusObjectPath &modem, modems) { QOfonoModemInterface device(modem.path()); if (device.isPowered() && device.isOnline()) - return modem;; + return modem; } return QDBusObjectPath(); } @@ -770,7 +770,7 @@ QVariantMap QOfonoDataConnectionManagerInterface::getProperties() return reply.value(); } -QOfonoPrimaryDataContextInterface::QOfonoPrimaryDataContextInterface(const QString &dbusPathName, QObject *parent) +QOfonoConnectionContextInterface::QOfonoConnectionContextInterface(const QString &dbusPathName, QObject *parent) : QDBusAbstractInterface(QLatin1String(OFONO_SERVICE), dbusPathName, OFONO_DATA_CONTEXT_INTERFACE, @@ -778,68 +778,68 @@ QOfonoPrimaryDataContextInterface::QOfonoPrimaryDataContextInterface(const QStri { } -QOfonoPrimaryDataContextInterface::~QOfonoPrimaryDataContextInterface() +QOfonoConnectionContextInterface::~QOfonoConnectionContextInterface() { } -bool QOfonoPrimaryDataContextInterface::isActive() +bool QOfonoConnectionContextInterface::isActive() { QVariant var = getProperty("Active"); return qdbus_cast<bool>(var); } -QString QOfonoPrimaryDataContextInterface::getApName() +QString QOfonoConnectionContextInterface::getApName() { QVariant var = getProperty("AccessPointName"); return qdbus_cast<QString>(var); } -QString QOfonoPrimaryDataContextInterface::getType() +QString QOfonoConnectionContextInterface::getType() { QVariant var = getProperty("Type"); return qdbus_cast<QString>(var); } -QString QOfonoPrimaryDataContextInterface::getName() +QString QOfonoConnectionContextInterface::getName() { QVariant var = getProperty("Name"); return qdbus_cast<QString>(var); } -QVariantMap QOfonoPrimaryDataContextInterface::getSettings() +QVariantMap QOfonoConnectionContextInterface::getSettings() { QVariant var = getProperty("Settings"); return qdbus_cast<QVariantMap>(var); } -QString QOfonoPrimaryDataContextInterface::getInterface() +QString QOfonoConnectionContextInterface::getInterface() { QVariant var = getProperty("Interface"); return qdbus_cast<QString>(var); } -QString QOfonoPrimaryDataContextInterface::getAddress() +QString QOfonoConnectionContextInterface::getAddress() { QVariant var = getProperty("Address"); return qdbus_cast<QString>(var); } -bool QOfonoPrimaryDataContextInterface::setActive(bool on) +bool QOfonoConnectionContextInterface::setActive(bool on) { // this->setProperty("Active", QVariant(on)); return setProp("Active", QVariant::fromValue(on)); } -bool QOfonoPrimaryDataContextInterface::setApn(const QString &name) +bool QOfonoConnectionContextInterface::setApn(const QString &name) { return setProp("AccessPointName", QVariant::fromValue(name)); } -void QOfonoPrimaryDataContextInterface::connectNotify(const QMetaMethod &signal) +void QOfonoConnectionContextInterface::connectNotify(const QMetaMethod &signal) { Q_UNUSED(signal); -// static const QMetaMethod propertyChangedSignal = QMetaMethod::fromSignal(&QOfonoPrimaryDataContextInterface::propertyChanged); +// static const QMetaMethod propertyChangedSignal = QMetaMethod::fromSignal(&QOfonoConnectionContextInterface::propertyChanged); // if (signal == propertyChangedSignal) { // if (!connection().connect(QLatin1String(OFONO_SERVICE), // this->path(), @@ -850,7 +850,7 @@ void QOfonoPrimaryDataContextInterface::connectNotify(const QMetaMethod &signal) // } // } -// static const QMetaMethod propertyChangedContextSignal = QMetaMethod::fromSignal(&QOfonoPrimaryDataContextInterface::propertyChangedContext); +// static const QMetaMethod propertyChangedContextSignal = QMetaMethod::fromSignal(&QOfonoConnectionContextInterface::propertyChangedContext); // if (signal == propertyChangedContextSignal) { // QOfonoDBusHelper *helper; // helper = new QOfonoDBusHelper(this); @@ -867,16 +867,16 @@ void QOfonoPrimaryDataContextInterface::connectNotify(const QMetaMethod &signal) // } } -void QOfonoPrimaryDataContextInterface::disconnectNotify(const QMetaMethod &signal) +void QOfonoConnectionContextInterface::disconnectNotify(const QMetaMethod &signal) { Q_UNUSED(signal); -// static const QMetaMethod propertyChangedSignal = QMetaMethod::fromSignal(&QOfonoPrimaryDataContextInterface::propertyChanged); +// static const QMetaMethod propertyChangedSignal = QMetaMethod::fromSignal(&QOfonoConnectionContextInterface::propertyChanged); // if (signal == propertyChangedSignal) { // } } -QVariant QOfonoPrimaryDataContextInterface::getProperty(const QString &property) +QVariant QOfonoConnectionContextInterface::getProperty(const QString &property) { QVariant var; QVariantMap map = getProperties(); @@ -888,13 +888,13 @@ QVariant QOfonoPrimaryDataContextInterface::getProperty(const QString &property) return var; } -QVariantMap QOfonoPrimaryDataContextInterface::getProperties() +QVariantMap QOfonoConnectionContextInterface::getProperties() { QDBusReply<QVariantMap > reply = this->call(QLatin1String("GetProperties")); return reply.value(); } -bool QOfonoPrimaryDataContextInterface::setProp(const QString &property, const QVariant &var) +bool QOfonoConnectionContextInterface::setProp(const QString &property, const QVariant &var) { QList<QVariant> args; args << QVariant::fromValue(property) << QVariant::fromValue(QDBusVariant(var)); diff --git a/src/plugins/bearer/connman/qofonoservice_linux_p.h b/src/plugins/bearer/connman/qofonoservice_linux_p.h index 00be9aa675..c73e8231a2 100644 --- a/src/plugins/bearer/connman/qofonoservice_linux_p.h +++ b/src/plugins/bearer/connman/qofonoservice_linux_p.h @@ -76,7 +76,7 @@ #define OFONO_NETWORK_OPERATOR_INTERFACE "org.ofono.NetworkOperator" #define OFONO_DATA_CONNECTION_MANAGER_INTERFACE "org.ofono.DataConnectionManager" #define OFONO_SIM_MANAGER_INTERFACE "org.ofono.SimManager" -#define OFONO_DATA_CONTEXT_INTERFACE "org.ofono.PrimaryDataContext" +#define OFONO_DATA_CONTEXT_INTERFACE "org.ofono.ConnectionContext" #define OFONO_SMS_MANAGER_INTERFACE "org.ofono.SmsManager" #define OFONO_PHONEBOOK_INTERFACE "org.ofono.Phonebook" @@ -281,14 +281,14 @@ protected: }; -class QOfonoPrimaryDataContextInterface : public QDBusAbstractInterface +class QOfonoConnectionContextInterface : public QDBusAbstractInterface { Q_OBJECT public: - explicit QOfonoPrimaryDataContextInterface(const QString &dbusPathName, QObject *parent = 0); - ~QOfonoPrimaryDataContextInterface(); + explicit QOfonoConnectionContextInterface(const QString &dbusPathName, QObject *parent = 0); + ~QOfonoConnectionContextInterface(); QVariantMap getProperties(); diff --git a/src/plugins/platforms/cocoa/qcocoabackingstore.mm b/src/plugins/platforms/cocoa/qcocoabackingstore.mm index a2f6910688..4881dcef71 100644 --- a/src/plugins/platforms/cocoa/qcocoabackingstore.mm +++ b/src/plugins/platforms/cocoa/qcocoabackingstore.mm @@ -73,7 +73,9 @@ QPaintDevice *QCocoaBackingStore::paintDevice() } #endif - m_qImage = QImage(m_requestedSize * scaleFactor, QImage::Format_ARGB32_Premultiplied); + QImage::Format format = window()->format().hasAlpha() + ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32; + m_qImage = QImage(m_requestedSize * scaleFactor, format); m_qImage.setDevicePixelRatio(scaleFactor); } return &m_qImage; @@ -92,7 +94,7 @@ void QCocoaBackingStore::flush(QWindow *win, const QRegion ®ion, const QPoint m_cgImage = 0; if (!m_qImage.isNull()) { if (QCocoaWindow *cocoaWindow = static_cast<QCocoaWindow *>(win->handle())) - [cocoaWindow->m_contentView flushBackingStore:this region:region offset:offset]; + [cocoaWindow->m_qtView flushBackingStore:this region:region offset:offset]; } } diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm index f33d4cb68b..d0fcf93b8c 100644 --- a/src/plugins/platforms/cocoa/qcocoaintegration.mm +++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm @@ -172,13 +172,13 @@ QPixmap QCocoaScreen::grabWindow(WId window, int x, int y, int width, int height windowSize.setHeight(windowRect.height()); } - QPixmap windowPixmap(windowSize); + QPixmap windowPixmap(windowSize * devicePixelRatio()); windowPixmap.fill(Qt::transparent); for (uint i = 0; i < displayCount; ++i) { const CGRect bounds = CGDisplayBounds(displays[i]); - int w = (width < 0 ? bounds.size.width : width); - int h = (height < 0 ? bounds.size.height : height); + int w = (width < 0 ? bounds.size.width : width) * devicePixelRatio(); + int h = (height < 0 ? bounds.size.height : height) * devicePixelRatio(); QRect displayRect = QRect(x, y, w, h); QCFType<CGImageRef> image = CGDisplayCreateImageForRect(displays[i], CGRectMake(displayRect.x(), displayRect.y(), displayRect.width(), displayRect.height())); diff --git a/src/plugins/platforms/cocoa/qcocoamenubar.mm b/src/plugins/platforms/cocoa/qcocoamenubar.mm index bae52c91b8..c0c8caed05 100644 --- a/src/plugins/platforms/cocoa/qcocoamenubar.mm +++ b/src/plugins/platforms/cocoa/qcocoamenubar.mm @@ -77,8 +77,10 @@ QCocoaMenuBar::~QCocoaMenuBar() [m_nativeMenu release]; static_menubars.removeOne(this); - if (m_window) + if (m_window && m_window->menubar() == this) { m_window->setMenubar(0); + updateMenuBarImmediately(); + } } void QCocoaMenuBar::insertMenu(QPlatformMenu *platformMenu, QPlatformMenu *before) diff --git a/src/plugins/platforms/cocoa/qcocoamenuitem.mm b/src/plugins/platforms/cocoa/qcocoamenuitem.mm index d78ff73bb6..bdcad6f490 100644 --- a/src/plugins/platforms/cocoa/qcocoamenuitem.mm +++ b/src/plugins/platforms/cocoa/qcocoamenuitem.mm @@ -315,9 +315,12 @@ NSMenuItem *QCocoaMenuItem::sync() return m_native; } +QT_BEGIN_NAMESPACE +extern QString qt_mac_applicationmenu_string(int type); +QT_END_NAMESPACE + QString QCocoaMenuItem::mergeText() { - extern QString qt_mac_applicationmenu_string(int type); QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *loader = getMenuLoader(); if (m_native == [loader aboutMenuItem]) { return qt_mac_applicationmenu_string(6).arg(qt_mac_applicationName()); diff --git a/src/plugins/platforms/cocoa/qcocoanativeinterface.h b/src/plugins/platforms/cocoa/qcocoanativeinterface.h index 9506f86238..2f79b49534 100644 --- a/src/plugins/platforms/cocoa/qcocoanativeinterface.h +++ b/src/plugins/platforms/cocoa/qcocoanativeinterface.h @@ -102,6 +102,9 @@ private: // QImage <-> CGImage conversion functions static CGImageRef qImageToCGImage(const QImage &image); static QImage cgImageToQImage(CGImageRef image); + + // Embedding NSViews as child QWindows + static void setWindowContentView(QPlatformWindow *window, void *nsViewContentView); }; #endif // QCOCOANATIVEINTERFACE_H diff --git a/src/plugins/platforms/cocoa/qcocoanativeinterface.mm b/src/plugins/platforms/cocoa/qcocoanativeinterface.mm index bd3a909137..9990537c1f 100644 --- a/src/plugins/platforms/cocoa/qcocoanativeinterface.mm +++ b/src/plugins/platforms/cocoa/qcocoanativeinterface.mm @@ -113,6 +113,8 @@ QPlatformNativeInterface::NativeResourceForIntegrationFunction QCocoaNativeInter return NativeResourceForIntegrationFunction(QCocoaNativeInterface::qImageToCGImage); if (resource.toLower() == "cgimagetoqimage") return NativeResourceForIntegrationFunction(QCocoaNativeInterface::cgImageToQImage); + if (resource.toLower() == "setwindowcontentview") + return NativeResourceForIntegrationFunction(QCocoaNativeInterface::setWindowContentView); return 0; } @@ -198,5 +200,10 @@ QImage QCocoaNativeInterface::cgImageToQImage(CGImageRef image) return qt_mac_toQImage(image); } +void QCocoaNativeInterface::setWindowContentView(QPlatformWindow *window, void *contentView) +{ + QCocoaWindow *cocoaPlatformWindow = static_cast<QCocoaWindow *>(window); + cocoaPlatformWindow->setContentView(reinterpret_cast<NSView *>(contentView)); +} QT_END_NAMESPACE diff --git a/src/plugins/platforms/cocoa/qcocoaservices.mm b/src/plugins/platforms/cocoa/qcocoaservices.mm index dea23e7e53..e4cec8c5f8 100644 --- a/src/plugins/platforms/cocoa/qcocoaservices.mm +++ b/src/plugins/platforms/cocoa/qcocoaservices.mm @@ -55,7 +55,7 @@ bool QCocoaServices::openUrl(const QUrl &url) const QString scheme = url.scheme(); if (scheme.isEmpty()) return openDocument(url); - return [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:QT_PREPEND_NAMESPACE(QCFString::toNSString)(url.toString())]]; + return [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:QT_PREPEND_NAMESPACE(QCFString::toNSString)(url.toString(QUrl::FullyEncoded))]]; } bool QCocoaServices::openDocument(const QUrl &url) diff --git a/src/plugins/platforms/cocoa/qcocoawindow.h b/src/plugins/platforms/cocoa/qcocoawindow.h index 70df7451f7..84dcaad206 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.h +++ b/src/plugins/platforms/cocoa/qcocoawindow.h @@ -121,6 +121,7 @@ public: void setParent(const QPlatformWindow *window); NSView *contentView() const; + void setContentView(NSView *contentView); void windowWillMove(); void windowDidMove(); @@ -164,8 +165,11 @@ public: // for QNSView friend class QCocoaBackingStore; friend class QCocoaNativeInterface; - QNSView *m_contentView; + NSView *m_contentView; + QNSView *m_qtView; NSWindow *m_nsWindow; + bool m_contentViewIsEmbedded; // true if the m_contentView is embedded in a "foregin" NSView hiearchy + QNSWindowDelegate *m_nsWindowDelegate; Qt::WindowFlags m_windowFlags; Qt::WindowState m_synchedWindowState; diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index fe6a9ad50b..4c58c22644 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -58,6 +58,11 @@ #include <QDebug> +enum { + defaultWindowWidth = 160, + defaultWindowHeight = 160 +}; + static bool isMouseEvent(NSEvent *ev) { switch ([ev type]) { @@ -186,6 +191,7 @@ static bool isMouseEvent(NSEvent *ev) QCocoaWindow::QCocoaWindow(QWindow *tlw) : QPlatformWindow(tlw) , m_nsWindow(0) + , m_contentViewIsEmbedded(false) , m_nsWindowDelegate(0) , m_synchedWindowState(Qt::WindowActive) , m_windowModality(Qt::NonModal) @@ -200,7 +206,8 @@ QCocoaWindow::QCocoaWindow(QWindow *tlw) #endif QCocoaAutoReleasePool pool; - m_contentView = [[QNSView alloc] initWithQWindow:tlw platformWindow:this]; + m_qtView = [[QNSView alloc] initWithQWindow:tlw platformWindow:this]; + m_contentView = m_qtView; setGeometry(tlw->geometry()); recreateWindow(parent()); @@ -237,6 +244,10 @@ void QCocoaWindow::setGeometry(const QRect &rect) void QCocoaWindow::setCocoaGeometry(const QRect &rect) { QCocoaAutoReleasePool pool; + + if (m_contentViewIsEmbedded) + return; + if (m_nsWindow) { NSRect bounds = qt_mac_flipRect(rect, window()); [m_nsWindow setContentSize : bounds.size]; @@ -538,7 +549,7 @@ void QCocoaWindow::setMask(const QRegion ®ion) if (m_nsWindow) [m_nsWindow setBackgroundColor:[NSColor clearColor]]; - [m_contentView setMaskRegion:®ion]; + [m_qtView setMaskRegion:®ion]; updateOpaque(); } @@ -583,6 +594,19 @@ NSView *QCocoaWindow::contentView() const return m_contentView; } +void QCocoaWindow::setContentView(NSView *contentView) +{ + // Remove and release the previous content view + [m_contentView removeFromSuperview]; + [m_contentView release]; + + // Insert and retain the new content view + [contentView retain]; + m_contentView = contentView; + m_qtView = 0; // The new content view is not a QNSView. + recreateWindow(parent()); // Adds the content view to parent NSView +} + void QCocoaWindow::windowWillMove() { // Close any open popups on window move @@ -595,7 +619,7 @@ void QCocoaWindow::windowWillMove() void QCocoaWindow::windowDidMove() { - [m_contentView updateGeometry]; + [m_qtView updateGeometry]; } void QCocoaWindow::windowDidResize() @@ -603,7 +627,7 @@ void QCocoaWindow::windowDidResize() if (!m_nsWindow) return; - [m_contentView updateGeometry]; + [m_qtView updateGeometry]; } void QCocoaWindow::windowWillClose() @@ -644,7 +668,9 @@ void QCocoaWindow::recreateWindow(const QPlatformWindow *parentWindow) m_nsWindowDelegate = 0; } - if (!parentWindow) { + if (window()->type() == Qt::SubWindow) { + // Subwindows don't have a NSWindow. + } else if (!parentWindow) { // Create a new NSWindow if this is a top-level window. m_nsWindow = createNSWindow(); setNSWindow(m_nsWindow); @@ -679,7 +705,8 @@ NSWindow * QCocoaWindow::createNSWindow() { QCocoaAutoReleasePool pool; - NSRect frame = qt_mac_flipRect(window()->geometry(), window()); + QRect rect = initialGeometry(window(), window()->geometry(), defaultWindowWidth, defaultWindowHeight); + NSRect frame = qt_mac_flipRect(rect, window()); Qt::WindowType type = window()->type(); Qt::WindowFlags flags = window()->flags(); diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index a8d8baa942..8f88387966 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -173,6 +173,36 @@ static QTouchDevice *touchDevice = 0; QWindowSystemInterface::handleExposeEvent(m_window, m_window->geometry()); } +- (void)viewDidMoveToSuperview +{ + if (!(m_window->type() & Qt::SubWindow)) + return; + + if ([self superview]) { + m_platformWindow->m_contentViewIsEmbedded = true; + QWindowSystemInterface::handleGeometryChange(m_window, m_platformWindow->geometry()); + QWindowSystemInterface::handleExposeEvent(m_window, m_platformWindow->geometry()); + QWindowSystemInterface::flushWindowSystemEvents(); + } else { + m_platformWindow->m_contentViewIsEmbedded = false; + } +} + +- (void)viewWillMoveToWindow:(NSWindow *)newWindow +{ + // ### Merge "normal" window code path with this one for 5.1. + if (!(m_window->type() & Qt::SubWindow)) + return; + + if (newWindow) { + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(windowNotification:) + name:nil // Get all notifications + object:newWindow]; + } else { + [[NSNotificationCenter defaultCenter] removeObserver:self name:nil object:[self window]]; + } +} - (void)updateGeometry { QRect geometry; @@ -181,6 +211,9 @@ static QTouchDevice *touchDevice = 0; NSRect rect = [self frame]; NSRect windowRect = [[self window] frame]; geometry = QRect(windowRect.origin.x, qt_mac_flipYCoordinate(windowRect.origin.y + rect.size.height), rect.size.width, rect.size.height); + } else if (m_window->type() & Qt::SubWindow) { + // embedded child window, use the frame rect ### merge with case below + geometry = qt_mac_toQRect([self bounds]); } else { // child window, use the frame rect geometry = qt_mac_toQRect([self frame]); @@ -198,6 +231,12 @@ static QTouchDevice *touchDevice = 0; // an infinite loop when this notification is triggered again.) m_platformWindow->QPlatformWindow::setGeometry(geometry); + // Don't send the geometry change if the QWindow is designated to be + // embedded in a foregin view hiearchy but has not actually been + // embedded yet - it's too early. + if ((m_window->type() & Qt::SubWindow) && !m_platformWindow->m_contentViewIsEmbedded) + return; + // Send a geometry change event to Qt, if it's ready to handle events if (!m_platformWindow->m_inConstructor) { QWindowSystemInterface::handleGeometryChange(m_window, geometry); @@ -322,7 +361,12 @@ static QTouchDevice *touchDevice = 0; ); CGImageRef bsCGImage = m_backingStore->getBackingStoreCGImage(); CGImageRef cleanImg = CGImageCreateWithImageInRect(bsCGImage, backingStoreRect); - CGContextSetBlendMode(cgContext, kCGBlendModeCopy); + + // Optimization: Copy frame buffer content instead of blending for + // top-level windows where Qt fills the entire window content area. + if (m_platformWindow->m_nsWindow) + CGContextSetBlendMode(cgContext, kCGBlendModeCopy); + CGContextDrawImage(cgContext, dirtyWindowRect, cleanImg); // Clean-up: diff --git a/src/plugins/platforms/qnx/qqnxwindow.cpp b/src/plugins/platforms/qnx/qqnxwindow.cpp index ab9c94772b..43e24034c9 100644 --- a/src/plugins/platforms/qnx/qqnxwindow.cpp +++ b/src/plugins/platforms/qnx/qqnxwindow.cpp @@ -272,9 +272,9 @@ void QQnxWindow::setVisible(bool visible) window()->requestActivate(); if (window()->isTopLevel()) { - if (visible) { - QWindowSystemInterface::handleExposeEvent(window(), window()->geometry()); - } else { + QWindowSystemInterface::handleExposeEvent(window(), window()->geometry()); + + if (!visible) { // Flush the context, otherwise it won't disappear immediately screen_flush_context(m_screenContext, 0); } diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp index a6709dffb3..f824666a54 100644 --- a/src/plugins/platforms/windows/qwindowscontext.cpp +++ b/src/plugins/platforms/windows/qwindowscontext.cpp @@ -849,10 +849,10 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message, return true; case QtWindows::ShowEvent: platformWindow->handleShown(); - return true; + return false; // Indicate transient children should be shown by windows (SW_PARENTOPENING) case QtWindows::HideEvent: platformWindow->handleHidden(); - return true; + return false;// Indicate transient children should be hidden by windows (SW_PARENTCLOSING) case QtWindows::CloseEvent: QWindowSystemInterface::handleCloseEvent(platformWindow->window()); return true; diff --git a/src/plugins/platforms/windows/qwindowsintegration.h b/src/plugins/platforms/windows/qwindowsintegration.h index 24dc01f0bd..ca484415be 100644 --- a/src/plugins/platforms/windows/qwindowsintegration.h +++ b/src/plugins/platforms/windows/qwindowsintegration.h @@ -78,7 +78,7 @@ public: # ifndef QT_NO_DRAGANDDROP virtual QPlatformDrag *drag() const; # endif -#endif !QT_NO_CLIPBOARD +#endif // !QT_NO_CLIPBOARD virtual QPlatformInputContext *inputContext() const; #ifndef QT_NO_ACCESSIBILITY virtual QPlatformAccessibility *accessibility() const; diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index cecbd81214..bb0092cd54 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -64,6 +64,11 @@ QT_BEGIN_NAMESPACE +enum { + defaultWindowWidth = 160, + defaultWindowHeight = 160 +}; + Q_GUI_EXPORT HICON qt_pixmapToWinHICON(const QPixmap &); static QByteArray debugWinStyle(DWORD style) @@ -198,17 +203,16 @@ static inline QSize clientSize(HWND hwnd) return qSizeOfRect(rect); } -// from qwidget_win.cpp/maximum layout size check removed. -static bool shouldShowMaximizeButton(Qt::WindowFlags flags) +// from qwidget_win.cpp +static bool shouldShowMaximizeButton(const QWindow *w) { - if (flags & Qt::MSWindowsFixedSizeDialogHint) + const Qt::WindowFlags flags = w->flags(); + if ((flags & Qt::MSWindowsFixedSizeDialogHint) || !(flags & Qt::WindowMaximizeButtonHint)) return false; // if the user explicitly asked for the maximize button, we try to add // it even if the window has fixed size. - if (flags & Qt::CustomizeWindowHint && - flags & Qt::WindowMaximizeButtonHint) - return true; - return flags & Qt::WindowMaximizeButtonHint; + return (flags & Qt::CustomizeWindowHint) || + w->maximumSize() == QSize(QWINDOWSIZE_MAX, QWINDOWSIZE_MAX); } // Set the WS_EX_LAYERED flag on a HWND if required. This is required for @@ -427,7 +431,7 @@ void WindowCreationData::fromWindow(const QWindow *w, const Qt::WindowFlags flag style |= WS_SYSMENU; if (flags & Qt::WindowMinimizeButtonHint) style |= WS_MINIMIZEBOX; - if (shouldShowMaximizeButton(flags)) + if (shouldShowMaximizeButton(w)) style |= WS_MAXIMIZEBOX; if (tool) exStyle |= WS_EX_TOOLWINDOW; @@ -468,6 +472,8 @@ QWindowsWindow::WindowData const QString windowClassName = QWindowsContext::instance()->registerWindowClass(w, isGL); + QRect rect = QPlatformWindow::initialGeometry(w, data.geometry, defaultWindowWidth, defaultWindowHeight); + if (title.isEmpty() && (result.flags & Qt::WindowTitleHint)) title = topLevel ? qAppName() : w->objectName(); @@ -476,14 +482,14 @@ QWindowsWindow::WindowData // Capture events before CreateWindowEx() returns. The context is cleared in // the QWindowsWindow constructor. - const QWindowCreationContextPtr context(new QWindowCreationContext(w, data.geometry, data.customMargins, style, exStyle)); + const QWindowCreationContextPtr context(new QWindowCreationContext(w, rect, data.customMargins, style, exStyle)); QWindowsContext::instance()->setWindowCreationContext(context); if (QWindowsContext::verboseWindows) qDebug().nospace() << "CreateWindowEx: " << w << *this << " class=" <<windowClassName << " title=" << title - << "\nrequested: " << data.geometry << ": " + << "\nrequested: " << rect << ": " << context->frameWidth << 'x' << context->frameHeight << '+' << context->frameX << '+' << context->frameY << " custom margins: " << context->customMargins; @@ -810,6 +816,7 @@ QWindowsWindow::QWindowsWindow(QWindow *aWindow, const WindowData &data) : QWindowsWindow::~QWindowsWindow() { #ifndef Q_OS_WINCE + QWindowSystemInterface::flushWindowSystemEvents(); if (QWindowsContext::instance()->systemInfo() & QWindowsContext::SI_SupportsTouch) QWindowsContext::user32dll.unregisterTouchWindow(m_data.hwnd); #endif // !Q_OS_WINCE diff --git a/src/plugins/platforms/xcb/qglxintegration.cpp b/src/plugins/platforms/xcb/qglxintegration.cpp index 2b18ecf7a4..5efac6ce12 100644 --- a/src/plugins/platforms/xcb/qglxintegration.cpp +++ b/src/plugins/platforms/xcb/qglxintegration.cpp @@ -105,57 +105,6 @@ static Window createDummyWindow(QXcbScreen *screen, GLXFBConfig config) return window; } -// Per-window data for active OpenGL contexts. -struct QOpenGLContextData -{ - QOpenGLContextData(Display *display, Window window, GLXContext context) - : m_display(display), - m_window(window), - m_context(context) - {} - - QOpenGLContextData() - : m_display(0), - m_window(0), - m_context(0) - {} - - Display *m_display; - Window m_window; - GLXContext m_context; -}; - -static inline QOpenGLContextData currentOpenGLContextData() -{ - QOpenGLContextData result; - result.m_display = glXGetCurrentDisplay(); - result.m_window = glXGetCurrentDrawable(); - result.m_context = glXGetCurrentContext(); - return result; -} - -static inline QOpenGLContextData createDummyWindowOpenGLContextData(QXcbScreen *screen) -{ - QOpenGLContextData result; - result.m_display = DISPLAY_FROM_XCB(screen); - - QSurfaceFormat format; - GLXFBConfig config = qglx_findConfig(DISPLAY_FROM_XCB(screen), screen->screenNumber(), format); - if (config) { - result.m_context = glXCreateNewContext(DISPLAY_FROM_XCB(screen), config, GLX_RGBA_TYPE, 0, true); - result.m_window = createDummyWindow(screen, config); - } else { - XVisualInfo *visualInfo = qglx_findVisualInfo(DISPLAY_FROM_XCB(screen), screen->screenNumber(), &format); - if (!visualInfo) - qFatal("Could not initialize GLX"); - result.m_context = glXCreateContext(DISPLAY_FROM_XCB(screen), visualInfo, 0, true); - result.m_window = createDummyWindow(screen, visualInfo); - XFree(visualInfo); - } - - return result; -} - static inline QByteArray getGlString(GLenum param) { if (const GLubyte *s = glGetString(param)) @@ -203,70 +152,7 @@ static void updateFormatFromContext(QSurfaceFormat &format) format.setProfile(QSurfaceFormat::CompatibilityProfile); } -/*! - \class QOpenGLTemporaryContext - \brief A temporary context that can be instantiated on the stack. - - Functions like glGetString() only work if there is a current GL context. - - \internal - \ingroup qt-lighthouse-xcb -*/ -class QOpenGLTemporaryContext -{ - Q_DISABLE_COPY(QOpenGLTemporaryContext) -public: - QOpenGLTemporaryContext(QXcbScreen *screen); - ~QOpenGLTemporaryContext(); - -private: - const QOpenGLContextData m_previous; - const QOpenGLContextData m_current; -}; - -QOpenGLTemporaryContext::QOpenGLTemporaryContext(QXcbScreen *screen) - : m_previous(currentOpenGLContextData()), - m_current(createDummyWindowOpenGLContextData(screen)) -{ - // Make our temporary context current on our temporary window - glXMakeCurrent(m_current.m_display, m_current.m_window, m_current.m_context); -} - -QOpenGLTemporaryContext::~QOpenGLTemporaryContext() -{ - // Restore the previous context if possible, otherwise just release our temporary context - if (m_previous.m_display) - glXMakeCurrent(m_previous.m_display, m_previous.m_window, m_previous.m_context); - else - glXMakeCurrent(m_current.m_display, 0, 0); - - // Destroy our temporary window - XDestroyWindow(m_current.m_display, m_current.m_window); - - // Finally destroy our temporary context itself - glXDestroyContext(m_current.m_display, m_current.m_context); -} - -QOpenGLDefaultContextInfo::QOpenGLDefaultContextInfo() - : vendor(getGlString(GL_VENDOR)), - renderer(getGlString(GL_RENDERER)) -{ - updateFormatFromContext(format); -} - -QOpenGLDefaultContextInfo *QOpenGLDefaultContextInfo::create(QXcbScreen *screen) -{ - // We need a current context for getGLString() to work. To have - // the QOpenGLDefaultContextInfo contain the latest supported - // context version, we rely upon the QOpenGLTemporaryContext to - // correctly obtain a context with the latest version - QScopedPointer<QOpenGLTemporaryContext> temporaryContext(new QOpenGLTemporaryContext(screen)); - QOpenGLDefaultContextInfo *result = new QOpenGLDefaultContextInfo; - return result; -} - - -QGLXContext::QGLXContext(QXcbScreen *screen, const QSurfaceFormat &format, QPlatformOpenGLContext *share, QOpenGLDefaultContextInfo *defaultContextInfo) +QGLXContext::QGLXContext(QXcbScreen *screen, const QSurfaceFormat &format, QPlatformOpenGLContext *share) : QPlatformOpenGLContext() , m_screen(screen) , m_context(0) @@ -294,51 +180,60 @@ QGLXContext::QGLXContext(QXcbScreen *screen, const QSurfaceFormat &format, QPlat QList<QByteArray> glxExt = QByteArray(glXQueryExtensionsString(DISPLAY_FROM_XCB(m_screen), m_screen->screenNumber())).split(' '); bool supportsProfiles = glxExt.contains("GLX_ARB_create_context_profile"); - // Use glXCreateContextAttribsARB if is available + // Use glXCreateContextAttribsARB if available if (glxExt.contains("GLX_ARB_create_context") && glXCreateContextAttribsARB != 0) { - // We limit the requested version by the version of the static context as - // glXCreateContextAttribsARB fails and returns NULL if the requested context - // version is not supported. This means that we will get the closest supported - // context format that that which was requested and is supported by the driver - const int maxSupportedVersion = (defaultContextInfo->format.majorVersion() << 8) - + defaultContextInfo->format.minorVersion(); - const int requestedVersion = qMin((m_format.majorVersion() << 8) + m_format.minorVersion(), - maxSupportedVersion); - const int majorVersion = requestedVersion >> 8; - const int minorVersion = requestedVersion & 0xFF; - - QVector<int> contextAttributes; - contextAttributes << GLX_CONTEXT_MAJOR_VERSION_ARB << majorVersion - << GLX_CONTEXT_MINOR_VERSION_ARB << minorVersion; - - // If asking for OpenGL 3.2 or newer we should also specify a profile - if (supportsProfiles && (m_format.majorVersion() > 3 || (m_format.majorVersion() == 3 && m_format.minorVersion() > 1))) { - if (m_format.profile() == QSurfaceFormat::CoreProfile) - contextAttributes << GLX_CONTEXT_PROFILE_MASK_ARB << GLX_CONTEXT_CORE_PROFILE_BIT_ARB; - else - contextAttributes << GLX_CONTEXT_PROFILE_MASK_ARB << GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB; - } - - int flags = 0; - - if (m_format.testOption(QSurfaceFormat::DebugContext)) - flags |= GLX_CONTEXT_DEBUG_BIT_ARB; - - // A forward-compatible context may be requested for 3.0 and later - if (m_format.majorVersion() >= 3 && !m_format.testOption(QSurfaceFormat::DeprecatedFunctions)) - flags |= GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB; - - if (flags != 0) - contextAttributes << GLX_CONTEXT_FLAGS_ARB << flags; - - contextAttributes << None; - - m_context = glXCreateContextAttribsARB(DISPLAY_FROM_XCB(screen), config, m_shareContext, true, contextAttributes.data()); - if (!m_context && m_shareContext) { - // re-try without a shared glx context - m_context = glXCreateContextAttribsARB(DISPLAY_FROM_XCB(screen), config, 0, true, contextAttributes.data()); - if (m_context) - m_shareContext = 0; + // Try to create an OpenGL context for each known OpenGL version in descending + // order from the requested version. + const int requestedVersion = format.majorVersion() * 10 + qMin(format.minorVersion(), 9); + + QVector<int> glVersions; + if (requestedVersion > 43) + glVersions << requestedVersion; + + // Don't bother with versions below 2.0 + glVersions << 43 << 42 << 41 << 40 << 33 << 32 << 31 << 30 << 21 << 20; + + for (int i = 0; !m_context && i < glVersions.count(); i++) { + const int version = glVersions[i]; + if (version > requestedVersion) + continue; + + const int majorVersion = version / 10; + const int minorVersion = version % 10; + + QVector<int> contextAttributes; + contextAttributes << GLX_CONTEXT_MAJOR_VERSION_ARB << majorVersion + << GLX_CONTEXT_MINOR_VERSION_ARB << minorVersion; + + // If asking for OpenGL 3.2 or newer we should also specify a profile + if (version >= 32 && supportsProfiles) { + if (m_format.profile() == QSurfaceFormat::CoreProfile) + contextAttributes << GLX_CONTEXT_PROFILE_MASK_ARB << GLX_CONTEXT_CORE_PROFILE_BIT_ARB; + else + contextAttributes << GLX_CONTEXT_PROFILE_MASK_ARB << GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB; + } + + int flags = 0; + + if (m_format.testOption(QSurfaceFormat::DebugContext)) + flags |= GLX_CONTEXT_DEBUG_BIT_ARB; + + // A forward-compatible context may be requested for 3.0 and later + if (version >= 30 && !m_format.testOption(QSurfaceFormat::DeprecatedFunctions)) + flags |= GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB; + + if (flags != 0) + contextAttributes << GLX_CONTEXT_FLAGS_ARB << flags; + + contextAttributes << None; + + m_context = glXCreateContextAttribsARB(DISPLAY_FROM_XCB(screen), config, m_shareContext, true, contextAttributes.data()); + if (!m_context && m_shareContext) { + // re-try without a shared glx context + m_context = glXCreateContextAttribsARB(DISPLAY_FROM_XCB(screen), config, 0, true, contextAttributes.data()); + if (m_context) + m_shareContext = 0; + } } } diff --git a/src/plugins/platforms/xcb/qglxintegration.h b/src/plugins/platforms/xcb/qglxintegration.h index d10b1d441b..7116b2389d 100644 --- a/src/plugins/platforms/xcb/qglxintegration.h +++ b/src/plugins/platforms/xcb/qglxintegration.h @@ -55,23 +55,10 @@ QT_BEGIN_NAMESPACE -class QOpenGLDefaultContextInfo -{ - Q_DISABLE_COPY(QOpenGLDefaultContextInfo) - QOpenGLDefaultContextInfo(); -public: - static QOpenGLDefaultContextInfo *create(QXcbScreen *screen); - - const QByteArray vendor; - const QByteArray renderer; - QSurfaceFormat format; -}; - - class QGLXContext : public QPlatformOpenGLContext { public: - QGLXContext(QXcbScreen *xd, const QSurfaceFormat &format, QPlatformOpenGLContext *share, QOpenGLDefaultContextInfo *defaultContextInfo); + QGLXContext(QXcbScreen *xd, const QSurfaceFormat &format, QPlatformOpenGLContext *share); ~QGLXContext(); bool makeCurrent(QPlatformSurface *surface); diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp index a36f823b7c..2467eb6e7a 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection.cpp @@ -222,7 +222,6 @@ void QXcbConnection::updateScreens() // Delete any existing screens which are not in activeScreens for (int i = m_screens.count() - 1; i >= 0; --i) { if (!activeScreens.contains(m_screens[i])) { - ((QXcbIntegration*)QGuiApplicationPrivate::platformIntegration())->removeDefaultOpenGLContextInfo(m_screens[i]); delete m_screens[i]; m_screens.removeAt(i); } diff --git a/src/plugins/platforms/xcb/qxcbintegration.cpp b/src/plugins/platforms/xcb/qxcbintegration.cpp index d0b0ab8d02..0a02ea02af 100644 --- a/src/plugins/platforms/xcb/qxcbintegration.cpp +++ b/src/plugins/platforms/xcb/qxcbintegration.cpp @@ -123,9 +123,6 @@ QXcbIntegration::QXcbIntegration(const QStringList ¶meters) QXcbIntegration::~QXcbIntegration() { -#if !defined(QT_NO_OPENGL) && defined(XCB_USE_GLX) - qDeleteAll(m_defaultContextInfos); -#endif qDeleteAll(m_connections); } @@ -186,14 +183,7 @@ QPlatformOpenGLContext *QXcbIntegration::createPlatformOpenGLContext(QOpenGLCont { QXcbScreen *screen = static_cast<QXcbScreen *>(context->screen()->handle()); #if defined(XCB_USE_GLX) - QOpenGLDefaultContextInfo *defaultContextInfo; - if (m_defaultContextInfos.contains(screen)) { - defaultContextInfo = m_defaultContextInfos.value(screen); - } else { - defaultContextInfo = QOpenGLDefaultContextInfo::create(screen); - m_defaultContextInfos.insert(screen, defaultContextInfo); - } - return new QGLXContext(screen, context->format(), context->shareHandle(), defaultContextInfo); + return new QGLXContext(screen, context->format(), context->shareHandle()); #elif defined(XCB_USE_EGL) return new QEGLXcbPlatformContext(context->format(), context->shareHandle(), screen->connection()->egl_display(), screen->connection()); @@ -312,21 +302,4 @@ QPlatformTheme *QXcbIntegration::createPlatformTheme(const QString &name) const return QGenericUnixTheme::createUnixTheme(name); } -/*! - Called by QXcbConnection prior to a QQnxScreen being deleted. - - Destroys and cleans up any default OpenGL context info for this screen. -*/ -void QXcbIntegration::removeDefaultOpenGLContextInfo(QXcbScreen *screen) -{ -#if !defined(QT_NO_OPENGL) && defined(XCB_USE_GLX) - if (!m_defaultContextInfos.contains(screen)) - return; - QOpenGLDefaultContextInfo* info = m_defaultContextInfos.take(screen); - delete info; -#else - Q_UNUSED(screen); -#endif -} - QT_END_NAMESPACE diff --git a/src/plugins/platforms/xcb/qxcbintegration.h b/src/plugins/platforms/xcb/qxcbintegration.h index 13b3b115ca..6db9d82cca 100644 --- a/src/plugins/platforms/xcb/qxcbintegration.h +++ b/src/plugins/platforms/xcb/qxcbintegration.h @@ -52,10 +52,6 @@ class QAbstractEventDispatcher; class QXcbNativeInterface; class QXcbScreen; -#if !defined(QT_NO_OPENGL) && defined(XCB_USE_GLX) -class QOpenGLDefaultContextInfo; -#endif - class QXcbIntegration : public QPlatformIntegration { public: @@ -99,8 +95,6 @@ public: QStringList themeNames() const; QPlatformTheme *createPlatformTheme(const QString &name) const; - void removeDefaultOpenGLContextInfo(QXcbScreen *screen); - private: QList<QXcbConnection *> m_connections; @@ -110,10 +104,6 @@ private: QScopedPointer<QPlatformInputContext> m_inputContext; QAbstractEventDispatcher *m_eventDispatcher; -#if !defined(QT_NO_OPENGL) && defined(XCB_USE_GLX) - mutable QHash<QXcbScreen *, QOpenGLDefaultContextInfo *> m_defaultContextInfos; -#endif - #ifndef QT_NO_ACCESSIBILITY QScopedPointer<QPlatformAccessibility> m_accessibility; #endif diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index c0ddf5c0ae..abd2f7a147 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -113,6 +113,10 @@ #endif #define XCOORD_MAX 16383 +enum { + defaultWindowWidth = 160, + defaultWindowHeight = 160 +}; //#ifdef NET_WM_STATE_DEBUG @@ -219,8 +223,16 @@ void QXcbWindow::create() QRect rect = window()->geometry(); QPlatformWindow::setGeometry(rect); - rect.setWidth(qBound(1, rect.width(), XCOORD_MAX)); - rect.setHeight(qBound(1, rect.height(), XCOORD_MAX)); + QSize minimumSize = window()->minimumSize(); + if (rect.width() > 0 || rect.height() > 0) { + rect.setWidth(qBound(1, rect.width(), XCOORD_MAX)); + rect.setHeight(qBound(1, rect.height(), XCOORD_MAX)); + } else if (minimumSize.width() > 0 || minimumSize.height() > 0) { + rect.setSize(minimumSize); + } else { + rect.setWidth(defaultWindowWidth); + rect.setHeight(defaultWindowHeight); + } xcb_window_t xcb_parent_id = m_screen->root(); if (parent()) @@ -436,15 +448,23 @@ void QXcbWindow::setGeometry(const QRect &rect) propagateSizeHints(); const QRect wmGeometry = windowToWmGeometry(rect); - const quint32 mask = XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y | XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT; - const qint32 values[] = { - qBound<qint32>(-XCOORD_MAX, wmGeometry.x(), XCOORD_MAX), - qBound<qint32>(-XCOORD_MAX, wmGeometry.y(), XCOORD_MAX), - qBound<qint32>(1, wmGeometry.width(), XCOORD_MAX), - qBound<qint32>(1, wmGeometry.height(), XCOORD_MAX), - }; - - Q_XCB_CALL(xcb_configure_window(xcb_connection(), m_window, mask, reinterpret_cast<const quint32*>(values))); + if (qt_window_private(window())->positionAutomatic) { + const quint32 mask = XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT; + const qint32 values[] = { + qBound<qint32>(1, wmGeometry.width(), XCOORD_MAX), + qBound<qint32>(1, wmGeometry.height(), XCOORD_MAX), + }; + Q_XCB_CALL(xcb_configure_window(xcb_connection(), m_window, mask, reinterpret_cast<const quint32*>(values))); + } else { + const quint32 mask = XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y | XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT; + const qint32 values[] = { + qBound<qint32>(-XCOORD_MAX, wmGeometry.x(), XCOORD_MAX), + qBound<qint32>(-XCOORD_MAX, wmGeometry.y(), XCOORD_MAX), + qBound<qint32>(1, wmGeometry.width(), XCOORD_MAX), + qBound<qint32>(1, wmGeometry.height(), XCOORD_MAX), + }; + Q_XCB_CALL(xcb_configure_window(xcb_connection(), m_window, mask, reinterpret_cast<const quint32*>(values))); + } xcb_flush(xcb_connection()); } @@ -563,6 +583,7 @@ void QXcbWindow::show() if (!transientXcbParent) transientXcbParent = static_cast<QXcbScreen *>(screen())->clientLeader(); if (transientXcbParent) { // ICCCM 4.1.2.6 + m_gravity = XCB_GRAVITY_CENTER; Q_XCB_CALL(xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, m_window, XCB_ATOM_WM_TRANSIENT_FOR, XCB_ATOM_WINDOW, 32, 1, &transientXcbParent)); @@ -1221,8 +1242,10 @@ void QXcbWindow::propagateSizeHints() QWindow *win = window(); - xcb_size_hints_set_position(&hints, true, rect.x(), rect.y()); - xcb_size_hints_set_size(&hints, true, rect.width(), rect.height()); + if (!qt_window_private(win)->positionAutomatic) + xcb_size_hints_set_position(&hints, true, rect.x(), rect.y()); + if (rect.width() < QWINDOWSIZE_MAX || rect.height() < QWINDOWSIZE_MAX) + xcb_size_hints_set_size(&hints, true, rect.width(), rect.height()); xcb_size_hints_set_win_gravity(&hints, m_gravity); QSize minimumSize = win->minimumSize(); |